BRDroid
BRDroid

Reputation: 4388

How to handle promises

I am having an issue with Promises, I have writted a function which tries to get data from Shared preferences and once I receive it, I return a Promise. In the function I am using it returns Unhandled promise rejection cannot read the property then of undefined

Here is my function which gets the data from shared preferences and returns a promise

  export function isMock(){
    const returned = getSharedPreferenceValue( Globals.SHARED_PREFERENCES_KEY_IS_TEST_USER).then ((isTestUser) => {  
        consoleLog('isMock - ' + isTestUser);//THIS LINE WORKS 
        return Promise.resolve(isTestUser === 'true' ? true : false);
      })
      .catch(err => {
        consoleLog('error -' + err);
        return {error:err, response: null};
      });
}

Here is the function where I am trying to use the above function.

export function login ( abcd, xyz ){

    const returned = isMock().then((isMock) => {
        //Do some based on isMock.
        console.log(`Login isMock - ` + isMock); //DOES NOT PRINT
    })
    .catch(error => {
          console.log('Login isMock - error - ' + JSON.stringify(error));
      });
}

Here is the error message

Possible Unhandled Promise Rejection (id: 0):
TypeError: Cannot read property 'then' of undefined
TypeError: Cannot read property 'then' of undefined

Could you please suggest where I am going wrong.

Update

After following the answer creating New promise resolved the issue in that function but the error was coming from another one.

function inMock which is now fixed

export function isMock(){
    return new Promise((resolve, reject) => {
        getSharedPreferenceValue(Globals.SHARED_PREFERENCES_KEY_IS_TEST_USER).then(isTestUser => {
          consoleLog('isMock - ' + isTestUser);
          resolve(isTestUser === 'true' ? true : false);
        }).catch(err => {
          consoleLog('error -' + err);
          reject(err)
        });
      });
}

isMock is called here and issue is in else statement which returns a promise

export function login ( ABCD, XYZ ){
    const returned = isMock().then((isMock) => {
        consoleLog('login Legacy API - isMock() - ' + isMock);//THIS WORKS
        if(!isMock){
            console.log('isMock is false');
        }else{

            consoleLog('mock data - ../mockData/login.json');
            var user = require('../mockData/login.json');//WORKS

            return Promise.resolve(user);//PROBLEM MIGHT BE HERE
        }
    })
    .catch(error => {
          console.log('Login isMock - error - ' + JSON.stringify(error));
      });
}

Main calling function of Login is here which gives me the error

loginUser_legacy = async (ABCD, XYZ) => {  
    const returned = await login(cardDigits, nationalIdNumber).then((res) => {
      consoleLog('res - ' + res);//DOES NOT WORK
    });

  }

Thanks R

Upvotes: 0

Views: 101

Answers (4)

Sanyam Jain
Sanyam Jain

Reputation: 1194

Try returning a new Promise.

export function isMock() {
  return new Promise((resolve, reject) => {
    getSharedPreferenceValue(Globals.SHARED_PREFERENCES_KEY_IS_TEST_USER).then(isTestUser => {
      consoleLog('isMock - ' + isTestUser);
      resolve(isTestUser === 'true' ? true : false)
    }).catch(err => {
      consoleLog('error -' + err);
      reject(err)
    })
  })
}

-- Update --

Promise.resolve(user) will return promise for this scope only which is isMock().

export function login ( ABCD, XYZ ){
  const returned = isMock().then((isMock) => {
      consoleLog('login Legacy API - isMock() - ' + isMock);
      if(!isMock){
          console.log('isMock is false');
      }else{

          consoleLog('mock data - ../mockData/login.json');
          var user = require('../mockData/login.json');

          return Promise.resolve(user); // This line will return Promise for this scope only (isMock function)
      }
  })
  .catch(error => {
        console.log('Login isMock - error - ' + JSON.stringify(error));
    });
}

So to fix this, return a new Promise.

export function login(ABCD, XYZ) {
  return new Promise((resolve, reject) => {
    isMock()
      .then((isMock) => {
        consoleLog(`login Legacy API - isMock() - ${isMock}`);
        if (!isMock) {
          consoleLog('isMock is false');
        } else {
          consoleLog('mock data - ../mockData/login.json');
          const user = require('../mockData/login.json');
          resolve(user);
        }
      })
      .catch((error) => {
        consoleLog(`Login isMock - error - ${JSON.stringify(error)}`);
        reject(error);
      });
  });
}

Upvotes: 0

Tobin
Tobin

Reputation: 2018

I think, are you not returning returned in isMock() ?

So although in the catch you return {error:err, response: null}, you never actually get an error as you are return Promise.resolve(isTestUser === 'true' ? true : false); which always returns a resolved (albeit resolved with a true or false) and thus never goes into the catch (which is also async so isn't aaccctually returned)

edit, possible what to do:

export function isMock(){
  return new Promise((res,rej)=> {
   getSharedPreferenceValue(Globals.SHARED_PREFERENCES_KEY_IS_TEST_USER).then ((isTestUser) => {  
    res(isTestUser === 'true')
  }).catch(rej)
 }

}

A new promise is returned; this will getSharedPreferenceValue, if this succeeds then resolve the new promise with your answer. If this fails, pass the error into the reject function which will also pass back to the isMock() caller which will catch it.

Upvotes: 2

Varun Suresh Kumar
Varun Suresh Kumar

Reputation: 879

you don't have to use Promise.resolve since getSharedPreferenceValue itself is a promise... you could try to return just the values....

also you should not resolve a promise inside a thenable function as per documentation

you could try this way or you could simply use async/await

export function isMock(){
const returned = getSharedPreferenceValue( Globals.SHARED_PREFERENCES_KEY_IS_TEST_USER).then ((isTestUser) => {  
    consoleLog('isMock - ' + isTestUser);//THIS LINE WORKS 
    return isTestUser === 'true' ? true : false;
  })
  .catch(err => {
    consoleLog('error -' + err);
    return {error:err, response: null};
  });

}

Upvotes: 0

Grazerbeam
Grazerbeam

Reputation: 365

Looks like the function should be getSharedPreferences() not getSharedPreferencesValue()

Upvotes: 1

Related Questions