1

I am wanting to stop a loop that i have when it matches a condition but its just not breaking ive tried try catch loops with throw e and throw new typeerror but its just not breaking how do i get it to break here is the code i want to break

LoginAuth = (Res) => {
    try {
        if (Res.username === this.state.Username && Res.password === this.state.Password) {
            return (
                this.setState({
                    isLoggedIn: true,
                }, function () {

                }),
                this.hideModal()
            );
        } else {
            console.log("Gets to login auth and false");
        }
}

I want to make it stop when the user input in state.username and state.password are equal to the one in the variable Res but i cant get it to stop looping how do i do this.

this is the function that calls this one

CheckLoginAuth() {
    console.log("gets to check login auth");
    console.log(this.state.AuthRes);
    console.log("Username=" + this.state.Username);
    console.log("Password=" + this.state.Password);
    var self = this;
    this.props.AuthRes.forEach(function (Res) {
        return (
            console.log("ID=" + Res.id),
            console.log("Username=" + Res.username),
            console.log("Password=" + Res.password),
            self.LoginAuth(Res)
        );
    });
}

edit

CheckLoginAuth() {
    console.log("gets to check login auth");
    console.log(this.state.AuthRes);
    console.log("Username=" + this.state.Username);
    console.log("Password=" + this.state.Password);
    this.props.AuthRes.some(function (Res) {
        console.log("ID=" + Res.id);
        console.log("Username=" + Res.username);
        console.log("Password=" + Res.password);
        if (Res.username === this.state.Username && Res.password === this.state.Password) {// the error is on this line saying it doesnt know what Username or Password are in the state
            return (
                this.setState({
                    isLoggedIn: true,
                }, function () {
                }),
                this.hideModal()
            );
        } else {
            console.log("Gets to login auth and false");
        }
    });
}

error is Cannot read property 'state' of undefined

LoginAuth = (Res) => {
    if (Res.username === this.state.Username && Res.password === this.state.Password) {
        return (
            this.setState({
                isLoggedIn: true,
            }, function () {
            }),
            this.hideModal()
        );
    } else {
        console.log("Gets to login auth and false");
    }
}
CheckLoginAuth() {
    console.log("gets to check login auth");
    console.log(this.state.AuthRes);
    console.log("Username=" + this.state.Username);
    console.log("Password=" + this.state.Password);
    var self = this;
    this.props.AuthRes.every(function (Res) {
        console.log("ID=" + Res.id);
        console.log("Username=" + Res.username);
        console.log("Password=" + Res.password);
        return (
            self.LoginAuth(Res)
        );
    });
}

loops through but stops on the first one weather its true or false

andy wilson
  • 920
  • 5
  • 16
  • 38

2 Answers2

2

There is no way to stop execution of a forEach(). In fact, the MDN states:

There is no way to stop or break a forEach() loop other than by throwing an exception. If you need such behavior, the forEach() method is the wrong tool. Use a plain loop instead. If you are testing the array elements for a predicate and need a Boolean return value, you can use every() or some() instead.

So, as suggested, you could use some() instead.

some() executes the callback function once for each element present in the array until it finds one where callback returns a truthy value (a value that becomes true when converted to a Boolean). If such an element is found, some() immediately returns true. Otherwise, some() returns false.


So your function could instead be written as:

this.props.AuthRes.some(function (Res) {
    return (
        console.log("ID=" + Res.id),
        console.log("Username=" + Res.username),
        console.log("Password=" + Res.password),
        self.LoginAuth(Res)
    );
});

this will stop the iteration once the callback returns true, or until you run out of elements to iterate through.


Edit

To solve the Cannot read property 'state' of undefined error, the simplest way is to use an arrow function:

this.props.AuthRes.some((Res) => {
Chris
  • 57,622
  • 19
  • 111
  • 137
  • Would i put my If statement inside checkLoginAuth cause it still loops through all if you type in the first one in the list – andy wilson Jul 07 '17 at 13:27
  • @andywilson, I'm not sure how your entire application works. So I cannot say exactly how and where certain code should go. All I can do is answer your question on how to break a loop once a condition is met. :) – Chris Jul 07 '17 at 13:30
  • @andywilson, if this answer was helpful to you please consider marking it as "accepted" and/or up-voting for visibility. – Chris Jul 07 '17 at 13:31
  • @Chirs it keeps looping over even though i have put the .some part and now it is giving me another error i will write the error in my edit – andy wilson Jul 07 '17 at 13:35
  • @andywilson, you need to make sure you return a truthy value when the condition is fulfilled. – Chris Jul 07 '17 at 13:36
  • So if i use .every instead it will loop through the first one and stop even if it is false why is this? – andy wilson Jul 07 '17 at 13:41
0

I have fixed it by making it break

my code was

LoginAuth = (Res) => {
if (Res.username === this.state.Username && Res.password === this.state.Password) {
    return (
        this.setState({
            isLoggedIn: true,
        }, function () {
        }),
        this.hideModal()
    );
} else {
    console.log("Gets to login auth and false");
}
}
CheckLoginAuth() {
    console.log("gets to check login auth");
    console.log(this.state.AuthRes);
    console.log("Username=" + this.state.Username);
    console.log("Password=" + this.state.Password);
    var self = this;
    this.props.AuthRes.every(function (Res) {
        console.log("ID=" + Res.id);
        console.log("Username=" + Res.username);
        console.log("Password=" + Res.password);
        return (
            self.LoginAuth(Res)
        );
    });
}

it is now

LoginAuth = (Res) => {
    if (Res.username === this.state.Username && Res.password === this.state.Password) {
            this.setState({
                isLoggedIn: true,
            })

            this.hideModal();
            return true;
    } else {
        console.log("Gets to login auth and false");
        return null;
    }
}
CheckLoginAuth() {
    console.log("gets to check login auth");
    console.log(this.state.AuthRes);
    console.log("Username=" + this.state.Username);
    console.log("Password=" + this.state.Password);
    var self = this;
    this.props.AuthRes.some(function (Res) {
        console.log("ID=" + Res.id);
        console.log("Username=" + Res.username);
        console.log("Password=" + Res.password);
        return self.LoginAuth(Res);
    });
}

i wasn't returning a truthy value or a falsy value

andy wilson
  • 920
  • 5
  • 16
  • 38