0

Trying to perform setState after the value return from checkPermissions(), however async-await didn't do the job.

I can't spot anything incorrect here, can you point out my mistake? FYI checkPermissions() accept a callback function as parameter.

async componentDidMount() {
    let authorizationStatus = false;
    await PushNotification.checkPermissions(function(permissions) { 
      console.log(permissions); 
      authorizationStatus = permissions.alert
      console.log('Run first')
    });

    console.log('Run after')
    this.setState({
     authorizationStatus,
    });
  }

Check Permissions Code (Android)

@ReactMethod
    public void checkPermissions(Promise promise) {
      ReactContext reactContext = getReactApplicationContext();
      NotificationManagerCompat managerCompat = NotificationManagerCompat.from(reactContext);
      promise.resolve(managerCompat.areNotificationsEnabled());
    }

Solution tried but failed: Only Run first is printed out, Run after does not.

async componentDidMount() {
    let authorizationStatus = false;
    PushNotification.checkPermissions(function(permissions) { 
      console.log(permissions); 
      authorizationStatus = permissions.alert
      console.log('Run first')
      this.setState({
       authorizationStatus,
      },()=>{console.log('Run after')});

    });
  }
Tommy Leong
  • 2,509
  • 6
  • 30
  • 54
  • 1
    If it accepts a callback function, it isn't promisified yet. Which means it doesn't return a Promise, and putting `await` in front has no effect. The fix here is simple: just move the `setState` part into the callback. –  Aug 18 '20 at 04:31
  • Does `PushNotification.checkPermissions` actually return a `Promise` to be `await`ed? – msbit Aug 18 '20 at 04:32
  • @ChrisG Updated question. I actually tried this before, however setState does not get performed. – Tommy Leong Aug 18 '20 at 04:39
  • There's a trailing comma after `authorizationStatus` but I don't see any way that it would print `Run first` but not `Run after`. Are you showing us actual code? Or did you edit it for the question here? –  Aug 18 '20 at 04:43
  • @ChrisG I only did masking to the code, otherwise these are the code I have in my project. I tried removing comma after `authorizationStatus`, it didn't work either. – Tommy Leong Aug 18 '20 at 04:47
  • 1
    I assume you're getting `this.setState is not a function`? That's because you need to use an arrow function instead, otherwise `this` no longer points to your Component instance. If you do that, it works fine: https://codesandbox.io/s/nostalgic-cdn-tw8dd?file=/src/App.js –  Aug 18 '20 at 04:55
  • Ahhhhhhhh. I'm not getting `this.setState is not a function`, weirdly it went through..BUT You are right about this, I forgotten about `this` keyword scope in `function` and `arrow function`. You're the man @ChrisG. Would you post your answer? I'm accepting your solution (: – Tommy Leong Aug 18 '20 at 05:07

1 Answers1

0

You are presumably looking for

async componentDidMount() {
  const permissions = await PushNotification.checkPermissions();
  console.log(permissions); 
  const authorizationStatus = permissions.alert
  console.log('Run first');

  console.log('Run after')
  this.setState({authorizationStatus});
}

You can only await a promise, you don't want to pass a callback.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • it's not my option to pass callback instead of getting a promise. That's what the library decided. – Tommy Leong Aug 18 '20 at 06:56
  • @TommyLeong OK, then you need to [promisify it](https://stackoverflow.com/q/22519784/1048572) yourself. But from the android declaration you posted it looked as if the method would already support promises natively. – Bergi Aug 18 '20 at 08:01