Search code examples
javascriptreactjsreactjs-flux

React Flux Loading Initial Data via API Call


I have been stuck on this issue for hours now. I want to implement the Flux architecture. I am trying to create a ToDo list. However, I want to load some initial data before hand. For example in my todoStore.js:

import { EventEmitter } from "events";

class ToDoStore extends EventEmitter {
    constructor(){
        super();
        this.bucket_list = [{
            id: 123,
            name: "Hi",
            isCompleted: false
        }]

    }

    getAll(){
        return this.bucket_list;
    }
}

I have some initial data here which is used by my todo.js:

import toDoStore from './stores/todoStore'

class BucketApp extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            bucket_list: toDoStore.getAll()
        };
    }

And this works fine and dandy. I have a store which is basically a collection that my component receives data from. However, now I want to initialize the data from a database. So I have updated my todoStore.js:

class BucketlistStore extends EventEmitter {
    constructor(){
        super();
        fetch(url)
            .then(d => d.json())
            .then(d => {
                this.bucket_list = d;
            });
    }

    getAll(){
        return this.bucket_list;
    }
}

However, the getAll() returns undefined. Why is this the case? What am I doing wrong?


Solution

  • It returns undefined because fetching data is async and during initialization this.bucket_list is undefined. Try this:

    class BucketlistStore extends EventEmitter {
        constructor(){
            super();
            this.bucket_list_promise = fetch(url)
                .then(d => d.json());
        }
    
        getAll(){
            return this.bucket_list_promise;
        }
    }
    

    then

    import toDoStore from './stores/todoStore'
    
    class BucketApp extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                loadingData: true,
                bucket_list: null
            };
        }
    
        componentWillMount(){
           toDoStore.getAll().then(result => {
              this.setState({ bucket_list: result, loadingData: false }) 
           })
        }