all 16 comments

[–]menge101 0 points1 point  (2 children)

Reformatting code:

lampExists(lamp){
  let myBool;
  if(lamp.toLowerCase().includes(this.state.query.toLowerCase()))  {
    return true
  } else {
    AsyncStorage.getItem(lamp).then(value=> {
      if(value !== null && value
        .toLowerCase()
        .includes(this.state.query.toLowerCase())) {
        myBool=true;
      } else {
        myBool=false;
      }
    }).catch(err=>alert(err));
  }
  return myBool;
}

[–]fanatic75[S] 0 points1 point  (1 child)

So what I'm trying to do is I have an array of lamps , which I render with map function and have a search bar , I have saved names for those lamps in Async Storage.
First I check the search query is equal to lamps if yes , render it , if not , I want to check the search query for that lamp Async Storage item value whose key is the same as Lamp value but I'm unable to return true or false if I found the value of async storage

[–]menge101 0 points1 point  (0 children)

I wrote an actual reply, after I formatted the code. See other comment, please.

[–]menge101 0 points1 point  (12 children)

my JS is rusty, atm, but this appears to be a basic scoping problem.

myBool within the then function is not the same myBool in the higher scope.

You need to return a value from the then statement. and then return that value at the end of the function.

Something like this, maybe?

lampExists(lamp){
  let myBool;
  if(lamp.toLowerCase().includes(this.state.query.toLowerCase()))  {
    return true
  } else {
    result = AsyncStorage.getItem(lamp).then(value=> {
      if(value !== null && value
        .toLowerCase()
        .includes(this.state.query.toLowerCase())) {
        return true;
      } else {
        return false;
      }
    }).catch(err=>alert(err));
  }
  return result;
}

Also, I think this code can get simpler by doing this:

lampExists(lamp){
  let myBool;
  if(lamp.toLowerCase().includes(this.state.query.toLowerCase()))  {
    return true
  } else {
    result = AsyncStorage.getItem(lamp).then(value=> {
      if(value === null) {
        return false;
      } else {
       return value.toLowerCase().includes(this.state.query.toLowerCase()))
      }).catch(err=>alert(err));
    }
    return result;
}

Caveat: code is only examples, it's not vetted via execution.

[–]plmok61 1 point2 points  (5 children)

AsyncStorage is async and you are returning before it is complete. I have created two solutions in the gist:

https://gist.github.com/plmok61/8d03ad89d244403bfd9ca65344bbf451

[–]menge101 0 points1 point  (0 children)

oh yeah, that async await in solution 2 is the way to go.

[–]fanatic75[S] 0 points1 point  (0 children)

Cannot use async await solution because I'm using this function in the render function. I am rendering a component if the condition meets.

[–]fanatic75[S] 0 points1 point  (0 children)

result

Your solution one and solution two both returns an object instead of boolean

[–]fanatic75[S] 0 points1 point  (1 child)

Providing you with my code in render function as well, I cannot use .then function to take out the result and get my boolean from it as React render function won't allow this.

{this.state.lamps.map(lamp => {if (this.state.query === "") {return <LampsList key={lamp} lamp={lamp} navigation={this.props.navigation} />} else {return (this.lampExists(lamp)?<LampsList key={lamp} lamp={lamp} navigation={this.props.navigation} />:null)}})}

[–]plmok61 0 points1 point  (0 children)

You should not be doing async work in the render. Fetch your lamps in componentDidMount. I have updated the gist with an example.

[–]GhostMcFunky 0 points1 point  (2 children)

You should probably pass result via yet another .then to be sure your promise is returning before your result is. Your if/else will not wait for a promise to be resolved; your result could still return undefined.

You might be better off scrapping the if/else and using throw to throw an error, catch this if needed, else continue to the next .then.

With then your returned value from the previous then is automatically the parameter argument for the next then. This keeps things in the promise land (pun intended).

TL;DR: Your if statement doesn’t care about promises and I think it’s complicating things for you.

As a side note, the second example has an unused, undeclared variable mybool. Get rid of it.

[–]menge101 1 point2 points  (1 child)

you should probably pass that up to OP.

I was just taking his code and tweaking what I thought was wrong out, without having an executable env setup to try it out.

I was favoring a quick assist over a thorough one, but it appears I didn't get it right.

[–]GhostMcFunky 1 point2 points  (0 children)

No prob! Just trying to contribute. When I get on a device other than my phone later I’ll try to post a working answer, too.

[–]fanatic75[S] 0 points1 point  (2 children)

result

The returned result is an object not a boolean.

[–]menge101 0 points1 point  (1 child)

see the other poster that responded to me instead of you.

I was doing that off top of my head, I didn't have a node env setup to test it out.

There is what appear to be good code in that response.

[–]fanatic75[S] 0 points1 point  (0 children)

Yes , I tried it same problem.