Javascript object retaining "old" properties, can't override?

Viewed 562

I have the following code:

    const readDataFromSql = () => {
        // going to have to iterate through all known activities + load them here
        let sql = "[...]"
        return new Promise((resolve, reject) => {
            executeSqlQuery(sql).then((dict) => {
                let loadedData = [];
                for (let key in dict) {
                    let newItemVal = new ItemVal("reading hw", 7121, progress.DONE);
                    loadedData.push(newItemVal);
                }
                resolve(loadedData);
            });
        });
    }

ItemVal implementation:

class ItemVal {
   constructor(name, time, type) {
      this.name = name
      this.time = time
      this.type = type 
   }
}

Let's assume that newItemVal = "reading hwj", 5081, progress.PAUSED when readDataFromSql() first runs.

readDataFromSql() is then again called after some state changes -- where it repulls some information from a database and generates new values. What is perplexing, however, is that when it is called the second time, newItemVal still retains its old properties (attaching screenshot below).

Am I misusing the new keyword? enter image description here

5 Answers

From what I can see in your example code, you are not mutating existing properties but creating a new object with the ItemVal constructor function and adding them to an array, that you then return as a resolved promise. Are you sure the examples you give a correct representation of what you are actually doing

Given that, I'm not sure what could be causing the issue you are having, but I would at least recommend a different structure for your code, using a simpler function for the itemVal.

Perhaps with this setup, you might get an error returned that might help you debug your issue.

const itemVal = (name, time, type) => ({ name, time, type })

const readDataFromSql = async () => {
  try {
    const sql = "[...]"
    const dict = await executeSqlQuery(sql)

    const loadedData = dict.map((key) =>
      ItemVal("reading hw", 7121, progress.DONE)
    )

    return loadedData
 

  } catch (error) {
    return error
  }
};

If the issue is not in the function, then I would assume that the way you handle the data, returned from the readDataFromSql function, is where the issue lies. You need to then share more details about your implementation.

const readDataFromSql = async () => {
        let sql = "[...]"        
------> await executeSqlQuery(sql).then((dict) => {

Use the await keyword instead of creating a new promise.

I did some modification and found that below code is working correctly, and updating the new values on each call.

const readDataFromSql = () => {     
      return new Promise((resolve, reject) => { 
            let loadedData = [];
                let randomVal = Math.random();
                let newItemVal = new ItemVal(randomVal*10, randomVal*100, randomVal*1000);
                loadedData.push(newItemVal); 
            resolve(loadedData);
    });
}

Could you recheck if you are using below line in the code, as it will instantiate object with same properties again and again.

let newItemVal = new ItemVal("reading hw", 7121, progress.DONE);

You can modify your code as below to simplify the problem.

const readDataFromSql = async () => {
// going to have to iterate through all known activities + load them here
let sql = "[...]"       // define sql properly

let result = await executeSqlQuery(sql);

let loadedData = [];
for (let row in result) {
        let newItemVal = new ItemVal(row.name, row.time, row.type);
        loadedData.push(newItemVal);
    }

    return loadedData;
}


class ItemVal {
    constructor(name, time, type) {
        this.name = name
        this.time = time
        this.type = type
    }
}

What you are talking about is an issue related to Object mutation in Redux, however, you didn't add any redux code. Anyway, you might be making some mistake while recreating(not mutating) the array. General solution is the use spread operator as:

loadedData = [ ...loadedData.slice(0) , ...newloadedData]

In Dropdown.js line 188 instead of console.log-ing your variable write debugger;

This will function as a breakpoint. It will halt your code and you can inspect the value by hovering your mouse over the code BEFORE the newItemVal is changed again.

I can see in your screenshot that the newItemVal is modified again after you log it.

Related