Jamie Hutber
Jamie Hutber

Reputation: 28126

Breaking out of node.js then()s

I am running through a whole of externally brought in data and at certain points I need to break and end my then chain and just redirect the page.

I have something like this:

Api file

gamesApi.getAllResultsWithTeamInformation(passData)
    .then(gamesApi.filterPreviousResults)
    .then(gamesApi.checkIfWeHaveGamesToSaveToDB) //Break at if nothing to save
    .then(gamesApi.loopAndSaveToDB)
    .then(gamesApi.selectLatestLeagueID)

Function where I want the break to happen

checkIfWeHaveGamesToSaveToDB: function (passData) {
    if(passData.uniqueData.length === 0){
        passData.req.flash('notice', 'Sorry there was nothing new to save);
        passData.res.redirect('/admin/games/' + passata.leagueInfo.year);
        passData.res.end();
    }else {
        return passData;
    }
},

However when passData.uniqueData.length === 0 is true, it will redirect the page, but the chain will carry on running. How can I break/stop if passData.uniqueData.length === 0 is true?

Upvotes: 0

Views: 245

Answers (2)

Jaromanda X
Jaromanda X

Reputation: 1

Change your checkIfWeHaveGamesToSaveToDB function as follows

checkIfWeHaveGamesToSaveToDB: function (passData) {
    if(passData.uniqueData.length === 0){
        passData.req.flash('notice', 'Sorry there was nothing new to save);
        passData.res.redirect('/admin/games/' + passata.leagueInfo.year);
        passData.res.end();
        // either
        return Promise.reject('nothing new to save'); 
        // or
        throw 'nothing new to save';
    }else {
        return passData;
    }
},

remember to add a .catch at the end of your "then" chain to handle the rejection properly (even do nothing)

Upvotes: 2

Tomas Kulich
Tomas Kulich

Reputation: 15668

I usually use on of two possible solutions.

Solution 1: nest your Promise

sth
.then(sth)
.then(sth)
.then(sth)
.then((result) => {
  if (looksGood(result)) {
    return sth
      .then(sth)
      .then(sth)
      .then(sth)
  } else {
    // do nothing?
  }
})

Solution 2: Throw custom error

sth
.then(sth)
.then(sth)
.then(sth)
.then((result) => {
  if (looksGood(result)) {
    return result
  } else {
    throw new AbortError()
  }
})
.then(sth)
.then(sth)
.then(sth)
.catch(...) // catch and ignore AbortError, rethrow anything else

I believe the pros&cons of both proposed solutions are pretty clear: Solution 1 looks ugly, Solution 2 misuses Error-throwing-mechanism - this is little controversial at least. Solution 2 can be done nicer by writing a few custom helpers for throwing / catching the AbortError.

My personal favorite is solution nr. 2: Having spent some time with Python, I don't see hacking with custom Exceptions as a necessarily bad idea.

Upvotes: 1

Related Questions