0

I am new to fetch and react.js and basically javascript, I am trying to create a new row in a table and just get an ID back (second then), the problem is that temp in the then domain is changing but its not changing outside it although I defined it as function level variable

handleAddRow({ newRowIndex }) {
        var temp = null;

        /////////////////////////////////////// updating records in db
        fetch(`${config.serverUrl}/criteriaAPI`,
        {
            method: "POST",
            dataType: 'json',
            headers: {
                    'Accept': 'application/json; charset=UTF-8',
                    'Content-Type': 'application/json; charset=UTF-8'
                }
        })
        .then(function(res){ return res.json(); })
        .then(function(data){  temp = data._id ;alert(temp)})
        //////////////////////////////////////
        console.log(temp);
        const newRow = {
            _id: temp,
            criteria_id: '',
            securityCriteria: '',
            description: '',
        };
       let rows = this.state.rows.slice();
        rows = update(rows, {$push: [newRow]});
    },



console.log(temp) = > null
alert(temp) = > id key : id value
Ayman
  • 13
  • 6
  • 1
    You need to remove `'Access-Control-Allow-Origin':'*', "Access-Control-Allow-Credentials" : true` from the `headers` part of your fetch call. Those are response headers, so if you’ve added those to the request because you’re getting a CORS error, that’s not gonna solve the problem. If you are getting a CORS error you should use https://stackoverflow.com/posts/45325697/edit to edit/update your answer to include the exact error message you’re seeing in your browser devtools console. – sideshowbarker Jul 26 '17 at 11:39
  • True I removed both lines nothing changed with respect to the CORS error I used to get it from the node.js server and it was a mistake to add them in react.js fetch request I guess the comment posted downwards is the problem – Ayman Jul 26 '17 at 11:47

2 Answers2

2

It looks like the problem is that you are calling console.log(temp) without waiting for the previous promises to complete, that is the execution has not yet come to the point where you assign value to temp variable. So the value of the temp variable does change - but it happens some time after console.log(temp) gets executed.

If you want to use temp variable and it is filled in the asynchronous manner - you must access it in the corresponding then handlers.

Amid
  • 21,508
  • 5
  • 57
  • 54
  • I though about this but the problem is that I cannot access `this.state.rows` inside the `.then` domain because they are defined in the react initial state – Ayman Jul 26 '17 at 11:48
  • do you think there is a way to implement a call back function inside the then? – Ayman Jul 26 '17 at 11:49
  • 1
    Keeping context of `this` is a known "issue", there are multiple ways to solve it, check this question: https://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-inside-a-callback – Amid Jul 26 '17 at 11:50
  • Thank you for the link, this is the new code `.then(function(data){ const newRow = { _id: data._id, criteria_id: '', securityCriteria: '', description: '', }; console.log(newRow); let rows = self.temp; rows = update(rows, {$merge: [newRow]}); console.log(rows); self.setState({ rows }); }) ` the problem now is that I want the class context to call setState from the class – Ayman Jul 26 '17 at 12:21
0

Solved by separating the fetch request into a single function, the problem was as mentioned above the fetch request is taking too much time, so I had another function handleAddRow() to wait for it using promises

addRow(){
        return fetch(`${config.serverUrl}/criteriaAPI`,
        {
            method: "POST",
            dataType: 'json',
            headers: {
                    'Accept': 'application/json; charset=UTF-8',
                    'Content-Type': 'application/json; charset=UTF-8',
                }
        }) 
            .then(response => {
                 return response.json()
            })
            .catch(err => {
                console.log("fetch error" + err);
            });

    },


     handleAddRow({ newRowIndex }) {
        this.addRow()
            .then(data => {  
                let row =  this.createSingleRow(data);
                console.log(row);
                let rows = this.state.rows.slice();
                rows = update(rows, {$push: row});
                console.log(rows);
                this.setState({ rows });
            });
    },

    createSingleRow(data) {
        console.log('Entered into createRows');
        let temp = [];
        temp.push({
                _id: data._id,
                criteria_id: data.criteria_id,
                securityCriteria: data.securityCriteria,
                description: data.description
            });

        //console.log(temp);
        return temp;
    },
Ayman
  • 13
  • 6