1

I have an array of plain objects (not being class instances) with some object properties and I'm looping through the array to assign classes to the array elements and their sub properties while remaining the values. For some reason the output array (if logged to console as a whole) contains objects whose sub properties (Project property) has the value of Project class' default constructor values (values from 'project' properties of the array elements from the input array are lost). HOWEVER(!!), if I log a single element of the array, it does contain the 'project' property with correct value (and class Project is applied correctly too). The console logs in my code are done in consecutive lines of code, there's nothing between them!

How is this possible? What kind of problem shows this bizzare kind of symptoms?

const workArr = tasksList.map(element => {
    element = Object.assign(new Task(), element);
    delete element.project; // Task's constructor contains project: new Project(), so 
                            // I'm removing this property to have it clean
    element.project = new Project({ ID: projectID, defaultProject: false });
    element.project = Object.assign(new Project(), element.project);
    return element;
});

console.log(workArr[0].project); // logs correct value of project property from initial 
                            // taskList elements' values. Project class is applied!   
console.log(workArr); // logs array of tasks all of which project properties have the 
        // correct Project class, but their values are defaults of Person constructor(?!)
console.log(workArr[0].project); // logs correct value of project property from initial 
                            // taskListValues. Project class is applied! 


// PROJECT CLASS DEFINITON - ACCESSES VUEX STORE
export class Project {
    constructor({ ID, defaultProject } = { ID: null, defaultProject: false }) {
        this.ID = ID || null;
        this.color = 'black';
        if (ID) {
            this.getInitData();
            return;
        }
        if (defaultProject) {
            this.ID = store.state.userSettings.defaultProject.ID;
        }
    }
    getInitData() {
        const soughtProject = store.state.dictionaries.projectsDictionary.find(element => element.ID === this.ID);
        Object.keys(this).forEach(key => {
            this[key] = soughtProject[key];
        });
    };
}

Remarks:

1) Importantly: this procedure WORKS CORRECTLY when it is run first time after reload or if it is run for the second time in a row by a parent method (which can also call similar procedures loading and processing other objects from server). I guess the problem might lie there, but the whole code is a bit too big to put in the question. And I don't see how those other procedures would impact this one in this particular way? I don't know how to debug this more, because when I look at a single element it seems to be processed correctly!

I'm just hoping that someone can point me into a general direction what to look for further.

2) The array comes from vue-resource HTTP response, but I don't know if it matters. Processing response with json() method has no effect on the issue.

3) I played around with the Person constructor but it seems to work fine.

4) I also tried to make sure that the Task constructor that calls "new Project" for project property does not cause the problem, so after applying Task class to task element I remove the project property and assign a fresh one. Did not help.

5) There's no async code here. Besides the third log was added to verify this possibility.

Eggon
  • 2,032
  • 2
  • 19
  • 38
  • 3
    Admittedly I haven't read through this quite enough to confirm this is the/a source of confusion, however it's important to note that logging objects or arrays does not display the value *at the time it was logged* - it displays the **current** value/contents. For example, if you logged an empty array, and then added 5 items to it, the log would show an array with 5 items (despite logging it when it was empty) - same with objects. Perhaps that relates to your confusion. [**A quick demonstration of what I mean.**](https://jsfiddle.net/x1a9muwz/) – Tyler Roper Aug 13 '19 at 18:30
  • It's unclear what you're asking. And, what is the purpose of this line `element.project = Object.assign(new Project(), element.project)`. project property is already set to an instance of `Project`. – adiga Aug 13 '19 at 18:34
  • @TylerRoper but they are logging `workArr` after `map` – adiga Aug 13 '19 at 18:36
  • @adiga OP noted that this isn't the entirety of their code. I was pointing this out in the event they may be changing it elsewhere and confused why the console.log is not accurately reflecting the values they expect. – Tyler Roper Aug 13 '19 at 18:38
  • Thank you very much guys!! I didn't know that console log would not evaluate objects immediately. That got me confused indeed. After logging stringified objects I was able to track the bug! @TylerRoper If you want reputation please put the anwer as answer not comment, so I can mark it. – Eggon Aug 14 '19 at 11:00
  • @adiga that applies to you too, thank you! :) – Eggon Aug 14 '19 at 11:01

0 Answers0