简体   繁体   中英

Update State after `axios.post()`

Scenario

Using the Express framework to modify a MongoDB I am able to add documents to a collection named faculties . Also, the dropdownbox displaying the property name of the documents in collection faculties , when I can inspect it after the post method is completed. However, when I pass the state, and retrieve the faculties collection from it with: const { faculties } = state; and then inspect the properties name of the array of documents of collection faculties , It doesn't show the most recent addition to the database. (I am looking for the property 'id' of the newly inserted faculty document with name exampleFaculty to implement many-to-many relationships).

Attempts

  1. I tried applying a forceUpdate() to update the state, however from what I understood, this updates the render instead of the state. Nevertheless the render is updated but the state is not. This is the implementation:
this.forceUpdate();
axios.post('http://localhost:3001/api/putFaculty', {name: message});
this.forceUpdate();
ManyToManyDbMain.Main(message,collectionName,this.state) // implement many to many relationships in db
  1. I tried this.setState(this.state); to update the state:
this.forceUpdate();
axios.post('http://localhost:3001/api/putFaculty', {name: message});
this.forceUpdate();
this.setState(this.state);
ManyToManyDbMain.Main(message,collectionName,this.state) // implement many to many relationships in db
  1. I tried directly calling the fetch method to update the state:
this.forceUpdate();
axios.post('http://localhost:3001/api/putFaculty', {name: message});
this.forceUpdate();
this.getFaculties()
this.setState(this.state);

ManyToManyDbMain.Main(message,collectionName,this.state) // implement many to many relationships in db

Where the fetch method consists of:

// read the mongodb collection faculties in database "education"
    getFaculties= () => {
        fetch('http://localhost:3001/api/getFaculties')
                .then((data) => data.json())
                //set property "faculties" within the state" (won't throw error if you haven't defined property "faculties" within state".
                .then((res) => this.setState({ faculties: res.data })); 
    };
  1. Using the response of the axiom.post(..) method to read the new faculties from that:
axios.post('http://localhost:3001/api/putFaculty', {name: message})
                          .then(response => {
                            const {faculties} = this.state;
                            alert(response.data)
                            alert(response.name)
                            faculties.push(response.data);
                            this.setState({faculties});
                          })

But that returns an object Object and I do not yet know how to read the properties of that object, I tried mapping it into a .name property with: response.map((dat) => dat.name) but the response had no function named map .

  1. Since the state gets automatically updated every second with:
this.getFaculties();
        if (!this.state.intervalIsSet) {
            let interval = setInterval(this.getFaculties, 1000);
            this.setState({ intervalIsSet: interval });
        }
  1. I tried adding a sleep method of 5 seconds with the false expectation that the state would automatically be updated before the state is passed to the ManyToManyDbMain.Main() method. Instead the website/code is frozen for 7 seconds, (meaning the state does not get updated either), before the code continues.

Question

How can I update the state after the axios.post() , so that the latest document of collection faculties is included in the state that is passed to the ManyToManyDbMain.Main(..) ?

Ignored shortcuts/XY-problem solutions:

The following solutions to the xy-problem are acknowledged but not persued.

  1. I could manually generate all the id's for all documents, and just push them to the database, that way I have the Id's in the App.js when I need them. However, the reason to implement many-to-many relationships in the DB, is because it is designed to be a small database used (potentially) by many users, hence I want to reduce computation time (applying search queries to find subset id's) at the cost of a bigger database. That also means I don't want to create a separate system in the website that manages all the created Id's and prevents double Id's when MongoDb already has an optimised Id allocation system.
  2. I could add a second loop every n-milliseconds that checks whether some boolean indicates whether a new faculty is added, and launch a "get Id method" from there. But I think that makes the code unnecessarily complex, difficult to test, potentially unreliable with multiple users, and computationally intensive, which I am trying to avoid.

You can use the axios .then() method to set the component's state.

for example -

axios.get('http://localhost:3001/api/getFaculties')
  .then(res => {
    /** Console here to get an actual response from server */
    console.log(res);
    this.setState({
      faculties: res.data.results
    });
  })
  .catch(function(error) {
    console.log(error);
  });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM