Jack N
Jack N

Reputation: 175

Promise rejects before finishing for loop

this might be a easy fix, but I am running into a problem with using a loop with a Promise. I am using Angular and Typescript.

As a backstory, I am trying to implement a very simple user authentication login page. I have a Array of User objects, each object containing a username, password, etc. On the login page, when the user inputs their User/Pass, clicks a "Login" button, a promise function fires which loops through the Array to see if there is a match between the Array and the user input.

Here's some pseudocode that I have written, where usersList is the array of Users and users.username and users.password is the user input.

for (var i = 0; i < this.usersList.length; i++) {
    if (this.usersList[i].email === user.username && this.usersList[i].password === user.password) {
        resolve({
            /* code */
        })
    } else {
        reject({
            message: "User/Password not found"
        })
    }

However, this only works for the first object in the list, since the Promise rejects on the first iteration of the for loop. How would I go ahead and fix this so that it only rejects after the loop has gone through every object in the Array?

Upvotes: 1

Views: 686

Answers (3)

Jamiec
Jamiec

Reputation: 136094

The obvious problem is you're calling reject as soon as one item has been checked and found to not match the input. The loop does continue, but by that point it's too late to resolve.

A better idea might be to filter your users list to see if the item exists, if it does, resolve else reject. Something like:

var foundItems = this.usersList.filter(u => u.username == user.username && u.password == user.password);
if(foundItems.length){
    resolve({
            /* code */
        });
}
else{
    reject({
            message: "User/Password not found"
        });
}

You could also use find with similar effect:

var user = this.usersList.find(u => u.username == user.username && u.password == user.password);
if(user){
    resolve({
            /* code */
        });
}
else{
    reject({
            message: "User/Password not found"
        });
}

Upvotes: 2

tech_amity
tech_amity

Reputation: 202

Promise reject at first iteration because it did not match the object at index(0) of Array and code inside the else loop executed. To resolve this problem you should write the code where the promise reject at last iteration if it not resolved in all iteration before the last one.

 for (var i = 0; i < this.usersList.length; i++) {
    if (this.usersList[i].email === user.username && this.usersList[i].password === user.password) {
        resolve({
            /* code */
        })
    } else if(i === this.usersList.length - 1) {
        reject({
            message: "User/Password not found"
        })
  }

Upvotes: 0

pegasuspect
pegasuspect

Reputation: 1031

You basically fix your code by moving the reject.

for (var i = 0; i < this.usersList.length; i++) {
    if (this.usersList[i].email === user.username && this.usersList[i].password === user.password) {
        resolve({
            /* code */
        })
        return
    }
}
reject({
    message: "User/Password not found"
})

You need to return to break the loop when found and also, if this code runs in a function, to stop the execution of function.

Upvotes: 1

Related Questions