0

I'm trying to populate a menu list from my PouchDB database, but I can't seem to return anything from within the promise I call after calling get on the db.

Here is my code:

<MenuList>
   {this.populateSavedClues()}
</MenuList>
.
.
.
populateSavedClues() {
    var db = this.db;
    db.get('roomClues').then(function (doc) {
        if (doc.clues == null || doc.clues == array()) {
          return <MenuItem onClick={() => this.handleClose()} align='start' size='small' >You have no saved clues for this room</MenuItem>;
        }
        else {
          return doc.clues.map((clue) => <MenuItem onClick={() => this.selectClue(clue)} align='start' size='small' >{clue}</MenuItem>);
        }
    }).catch(function (err) {
        if(err.name=="not_found") {
          return <MenuItem onClick={() => this.handleClose()} align='start' size='small' >You have no saved clues for this room</MenuItem>;
        }
    });
  }

Now right now I'm specifically testing the catch condition. I know for a fact its hitting the not found in my tests, and hitting that return statement within, but my menu gets no items and is still empty. I've tested outside the promises and just make this function return the menu item with no other logic and that also works, so its something about trying to return within the catch promise and I am at my wits end trying to figure out why that return is not going all the way through to the MenuList call. What do I need to do to return the menu item?

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Chris
  • 35
  • 6
  • 1
    Possible duplicate of [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) – dotconnor Nov 26 '18 at 16:32
  • just a side note.. if you use onClick={ () => { this.someMethod() } } you can simply write it as onClick={this.someMethod()} - that way you don't create an anonymous function on rendering for each function call. – noa-dev Nov 28 '18 at 15:06
  • 1
    @noa-dev That is not entirely correct. First off the brackets need to be skipped, e.g. `onClick={this.someMethod}`. Second, if the method hasn't been bound to the component instance it will be triggered with an incorrect context, so `this` inside the method will not be correct. Using an arrow function inside the onClick is actually a way to preserve the context of the component. – Pehota Nov 28 '18 at 15:14
  • Yea, sorry forgot to delete the (). Wondering how an anonymous arrow function preserves the context though, as it, by default inherits the context from its wrapping scope. – noa-dev Nov 29 '18 at 07:04

1 Answers1

0
renderMenu() {
        let jsx;
        if (this.state.clues.length == 0) {
            jsx = <MenuItem onClick={() => this.handleClose()} align='start' size='small' >You have no saved clues for this room</MenuItem>
        } else {
            jsx = this.state.clues.map((clue) => {
                return <MenuItem onClick={() => this.selectClue(clue)} align='start' size='small' >{clue}</MenuItem>
            })
        }

        return jsx;
    }

    async populateSavedClues() {
        var db = this.db;
        try {
            const doc = await db.get('roomClues');
            return doc;         

        } catch (error) {
            alert('Error fetching clues...')
        }
    }



async componentDidMount() {

        const doc=  await this.populateSavedClues();

        this.setState({ clues: doc.clues });
    }

In your JSX:

<MenuList>
   {this.renderMenu()}
</MenuList>

Remember to put a "clues"(empty array) property in your state. Hope this helps.

i.brod
  • 3,993
  • 11
  • 38
  • 74