user9105849
user9105849

Reputation:

How to avoid nesting structure of callbacks with promises? [finished]

I am using promises to avoid the nesting structure created by callbacks.

However in this code I still have some nesting. Is there something I am doing wrong or is this un-avoidable in this case?

In this case I want to check and see if a profile exists and if it does not I want to create it.

  DB.getProfile(id_google).then((resGet) => {
    if(!resGet[0]){
      console.log('PROFILE - NOT FOUND - MUST CREATE');

      DB.createProfile(id_google, email, name, pic_url).then((resCreate)=>{
        console.log('PROFILE CREATED');
      }).catch((error) => {
        console.log('ERROR - createProfile() Failed: ', error);
      });

    } else {
      console.log('PROFILE FOUND LOCALLY');
      console.log(resGet[0]);
      return done(null, resGet[0])
    }
  }).catch((error) => {
      console.log('ERROR - getOrCreateProfile() Failed: ', error);
  });
};

Upvotes: 1

Views: 803

Answers (2)

Kousha
Kousha

Reputation: 36229

You can return and chain using multiple then

DB.getProfile(id_google)
    .then((resGet) => {
        if (!resGot[0]) {
            return DB.createProfile(id_google, email, name, pic_url);
        }
        return resGot[0];
    })
    .then((res) => {
        callback(null, res)
    })
    .catch((error) => {
        console.log('ERROR - getOrCreateProfile() Failed: ', error);
    });

If resGot[0] exist, then it is returned, and in the second then the variable res is that value. If it does not, then the promise of createProfile is returned and the value of res is whatever that function returns

Upvotes: 4

boysimple dimple
boysimple dimple

Reputation: 199

Sometimes it helps to boil your code down to the essentials:

getProfile
  if not found, 
    createProfile
       return profile
  else
    done profile

Presumably, you want to get createProfile outside in the same chain as the rest of the promise.

I changed the structure to:

getProfile
  if found, return profile 
  createProfile
    return profile
then
  done(profile)

It isn't really possible to have just one degree of nesting in this case. But you can reduce some level of nesting.

DB.getProfile(id_google)
.then((resGet) => {
    if(resGet[0]) {
      console.log('PROFILE FOUND LOCALLY');
      return resGet[0];
    }
    console.log('PROFILE - NOT FOUND - MUST CREATE');
    return DB.createProfile(id_google, email, name, pic_url)
    .then((resCreate)=>{
      console.log('PROFILE CREATED');
      return resCreate[0]; //Assuming resCreate looks like resGet
    })
  }
})
.then(profile=> {
    //The done function which belongs to passport is called once here.
    console.log(profile);
    return done(null, resGet[0])
})
.catch((error) => {
    console.log('ERROR - getOrCreateProfile() Failed: ', error);
});

Upvotes: 0

Related Questions