Marcin
Marcin

Reputation: 102

ReactJS - how can I handle notifications to user based on server response?

so I've been trying to figure out

how to handle some notifications/alerts to show users some information based on what they typed in for example login form.

const DoLogin = async (email, password) => {
  const loginTeacher = await axios.post(
    "http://localhost:3000/teachers/login",
    {
      email,
      password
    }
  );
  return loginTeacher;
};

class Login extends React.Component {
  state = {
    email: "",
    password: "",
    logged: false,
    status: "",
    errorMessage: ""
  };

  onEmailChange = e => {
    this.setState({
      email: e.target.value
    });
  };

  onPassChange = e => {
    this.setState({
      password: e.target.value
    });
  };

  onSubmit = e => {
    e.preventDefault();
    DoLogin(this.state.email, this.state.password)
      .then(res => {
        localStorage.setItem("mysecrettoken", res.data.token);
        this.setState({ teacher: res.data, logged: true, status: res.status });
        alert("Successfully logged in");
      })
      .catch(err => {
        alert("Unable to login in, user not found");
      });
  };

  loginForm() {
    return (
      <div className="Login form">
        <form onSubmit={this.onSubmit}>
          <label htmlFor="email">
            Email:
            <input
              type="text"
              name="email"
              value={this.state.email}
              onChange={this.onEmailChange}
            />
          </label>
          <br />
          <label htmlFor="password">
            Hasło:
            <input
              type="password"
              name="password"
              value={this.state.password}
              onChange={this.onPassChange}
            />
          </label>
          <br />
          <input type="submit" value="Zaloguj" />
          <input type="button" value="Dodaj nauczyciela" />
        </form>
      </div>
    );
  }
}

Now, whenever a user is able to login it shows alert with the message, but I don't think that's a good way to show user information.

Could you please help me with that? Some articles/libraries would be great. I've tried to implement react toast but I failed to do that.

Upvotes: 2

Views: 748

Answers (1)

zavr
zavr

Reputation: 2129

You can store the details in the state (like you already do) and then access in the render method for conditional rendering if the user has logged in.

const DoLogin = async (email, password) => {
  const loginTeacher = await axios.post(
    "http://localhost:3000/teachers/login",
    {
      email,
      password
    }
  );
  return loginTeacher;
};

class Login extends React.Component {
  state = {
    email: "",
    password: "",
    logged: false,
    status: "",
    errorMessage: ""
  };

  onEmailChange = e => {
    this.setState({
      email: e.target.value
    });
  };

  onPassChange = e => {
    this.setState({
      password: e.target.value
    });
  };

  onSubmit = e => {
    e.preventDefault();
    DoLogin(this.state.email, this.state.password)
      .then(res => {
        localStorage.setItem("mysecrettoken", res.data.token);
        this.setState({ teacher: res.data, logged: true, status: res.status, showingMessage: true });
        setTimeout(() => { 
           this.setState({ showingMessage: false })
        }, 2000)
        alert("Successfully logged in");
      })
      .catch(err => {
        // update state with ERROR
        this.setState({ error: err.message })
        alert("Unable to login in, user not found");
      });
  };

  loginForm() {
    if (this.state.logged && this.state.showingMessage) {
      return (<div>You've logged in as {this.state.teacher.name}</div>)
    }
    return (
      <div className="Login form">
        {/* display ERROR */}
        {this.state.error && <span style="color:red">
          There was an error during registration: {this.state.error}.
        </span>}
        <form onSubmit={this.onSubmit}>
          <label htmlFor="email">
            Email:
            <input
              type="text"
              name="email"
              value={this.state.email}
              onChange={this.onEmailChange}
            />
          </label>
          <br />
          <label htmlFor="password">
            Hasło:
            <input
              type="password"
              name="password"
              value={this.state.password}
              onChange={this.onPassChange}
            />
          </label>
          <br />
          <input type="submit" value="Zaloguj" />
          <input type="button" value="Dodaj nauczyciela" />
        </form>
      </div>
    );
  }
}

I don't know where your render method is, but basically just access the state. You can also set a timeout after you received the data, and add another property on the state, like showingMessage which will be true at first, and then in say 2s will be false, then your condition would be if (this.state.logged & this.state.showingMessage).

Upvotes: 2

Related Questions