Home > database >  Stop react redirecting before API call has finsished
Stop react redirecting before API call has finsished

Time:02-23

Im writing an application using react and django rest. I am trying to update a post and then redirect back to the home screen, but sometimes the redirect happens before the put request.

As there is a Get request on the home page, that then gets called first and i do not see the updated values unless i refresh the page? Any suggestions?

Here is the page with the put request (updateNote())

import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";
import { ReactComponent as ArrowLeft } from "../assets/arrow-left.svg";

const NotePage = ({ match, history }) => {
  let noteId = match.params.id;
  let [note, setNote] = useState(null);

  useEffect(() => {
    getNote();
  }, [noteId]);

  let getNote = async () => {
    let response = await fetch(`/api/get-note/${noteId}/`);
    let data = await response.json();
    setNote(data);
  };

  let updateNote = async () => {
    fetch(`/api/get-note/${noteId}/update/`, {
      method: "PUT",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(note),
    });
  };

  let deleteNote = async () => {
    fetch(`/api/get-note/${noteId}/delete/`, {
      method: "DELETE",
      headers: {
        "Content-Type": "application/json",
      },
    });
    history.push("/");
  };
  let handleSubmit = () => {
    updateNote().then(history.push("/"));
  };

  let handleChange = (value) => {
    setNote((note) => ({ ...note, body: value }));
    console.log("Handle Change:", note);
  };

  return (
    <div className="note">
      <div className="note-header">
        <h3>
          <ArrowLeft onClick={handleSubmit} />
        </h3>
        <button onClick={deleteNote}>Delete</button>
      </div>
      <textarea
        onChange={(e) => {
          handleChange(e.target.value);
        }}
        value={note?.body}
      ></textarea>
    </div>
  );
};

export default NotePage;

Then here is the page it redirects to

import React, { useState, useEffect } from "react";
import ListItem from "../components/ListItem";

const NotesListPage = () => {
  let [notes, setNotes] = useState([]);

  useEffect(() => {
    getNotes();
  }, []);

  let getNotes = async () => {
    let response = await fetch("/api/get-notes/");
    let data = await response.json();
    setNotes(data);
  };

  return (
    <div className="notes">
      <div className="notes-header">
        <h2 className="notes-title">&#9782; Notes</h2>
        <p className="notes-count">{notes.length}</p>
      </div>
      <div className="notes-list">
        {notes.map((note, index) => (
          <ListItem key={index} note={note} />
        ))}
      </div>
    </div>
  );
};

export default NotesListPage;

I want to make sure that history.push("/") doesnt get executed unitll the fetch request has returned a response

CodePudding user response:

I suggest using the promise method and using '.then' or await just like that :

let updateNote = async () => {
    let temp =await fetch(`/api/get-note/${noteId}/update/`, {
      method: "PUT",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(note),
    });
  if(temp)
     history.push("/")
  };

CodePudding user response:

If you want to navigate after the fetch request has resolved then the code needs to wait for them to settle. Don't forget to catch and/or handle any errors and rejected Promises appropriately.

Example:

const updateNote = async () => {
  // return Promise to chain from
  return fetch(`/api/get-note/${noteId}/update/`, {
    method: "PUT",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify(note),
  });
};

const deleteNote = async () => {
  try {
    // wait for Promise to resolve
    await fetch(`/api/get-note/${noteId}/delete/`, {
      method: "DELETE",
      headers: {
        "Content-Type": "application/json",
      },
    });
    history.push("/");
  } catch(error) {
    // log error, etc...
  }
};

const handleSubmit = () => {
  // pass a callback in .then
  updateNote()
    .then(() => history.push("/"))
    .catch(error => {
      // log error, etc...
    });
};
  • Related