1

I'm trying to store persistent data for an an electron app with electron-json-storage, I tried using neDB but it would throw this error so I switched however it looks like it's not neDB's issue but my own.

Here is the problem: I'm trying to get information out of the storage and when I call the respective get method and put the information out to the console everything seems fine inside the Getmethod, everything even seems fine when i do console.log(Get()) but as soon as I try to map it or get the length of the returned array it thinks that array is empty.

Here is my code:

import * as React from "react";
import { Component } from "react";
import { ToastContainer } from "react-toastify";
import { connect } from "react-redux";
import GetAllCharacters from "../../scripts/GetAllCharacters";
const mapStateToProps = (state) => {
    return {
        character: state,
    };
};

const mapDispatchToProps = (dispatch) => ({});

const Sheet = (props) => {
    const [characters, setCharacters] = React.useState();
    return (
        <div className="container-fluid">
            <div className="row" style={{ marginRight: "0px" }}>
                {props.character != null ? (
                    <>
                        //Code Removed for irrelevancy
                    </>
                ) : (
                    <>
                    {console.log(GetAllCharacters()}<--prints an array of characters to the console
                    {GetAllCharacters().length}</><--returns 0 despite the fact it just printed the characters to the console
                )}
            </div>
        </div>
    );
};

export default connect(mapStateToProps, mapDispatchToProps)(Sheet);

GetAllCharacters()

import { Character } from "../Data/Character";

function GetAllCharacters() {
    var returnCharacters: Character[] = [];
    const storage = require("electron-json-storage");

    storage.getAll(function (error, data) {
        if (error) throw error;
        Object.entries(data).map((c) => {
            returnCharacters.push(<Character>c[1]);
        });
    });
    console.log(returnCharacters);
    return returnCharacters;
}
export default GetAllCharacters;
Markus Zeller
  • 8,516
  • 2
  • 29
  • 35
  • Could you try `[...GetAllCharacters()].length()` ? – Antonio Erdeljac Aug 05 '20 at 14:47
  • _"<--prints an array of characters to the console"_ - No, it will print an empty array (`[ ]` without any elements in it). Only after expanding it in the console you will see the elements and the `.length` will be non-zero. Try `console.log(JSON.stringify(GetAllCharacters())}` and you will only get an empty array. – Andreas Aug 05 '20 at 14:49
  • 1
    [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Andreas Aug 05 '20 at 14:50
  • what you will sew in that case: `console.log(Array.isArray(Get()))` – Arseniy-II Aug 05 '20 at 14:50
  • 1
    If you're not interested in the return value of `Array.prototype.map()` then `.map()` is the wrong method. Use a `.forEach()` or refactor your function. – Andreas Aug 05 '20 at 14:52

1 Answers1

2

GetAllCharacters should be an async function (since it fetch some async datas). GetAllCharacters().length will always be 0 since GetAllCharacters() returns an empty array.

function GetAllCharacters() {
    var returnCharacters: Character[] = [];
    const storage = require("electron-json-storage");
    // ** HERE IS THE PROBLEM ** This is async. and the next line will get runned instantly and donesn't wait for it to get the data.
    storage.getAll(function (error, data) {
        if (error) throw error;
        Object.entries(data).map((c) => {
            returnCharacters.push(<Character>c[1]);
        });
    });
    // ** Now returnCharacters is empty array, and it will return it.
    console.log(returnCharacters);
    return returnCharacters;
}

you should correct your GetAllCharacters function to get all the results asyncronously and at the end return the result array (with callback for example). and then you should call GetAllCharacters(result => {setCharacters(result)}) in your component with useEffect for example, and then bind the characters to render.

yaya
  • 7,675
  • 1
  • 39
  • 38