gj1118's avatar

array.push is creating duplicates

Hi, I have two arrays

        stepInfo: {
                    stepName:null,
                    stepColor:null,
                },

and

steps:[]

In the UI , I am doing something like the following

<input type="text" placeholder="Add new step." v-model="stepInfo.stepName" class="input input-sm form-control steptext">
<select id="type" class="typePicker form-control" data-live-search="true" title="Please select a type" v-model="stepInfo.stepColor">
    <option>Info</option>
    <option>Error</option>
    <option>Warning</option>
    <option>Success</option>
    <option>Default</option>
</select>
<span class="input-group-btn">
    <button type="button" v-on:click="addStepToTask()" class="btn btn-sm btn-white"> <i class="fa fa-plus"></i> Add Step</button>
</span>

and my addStepToTask function looks like as follows

addStepToTask : function() {
    console.info("test steps : " + JSON.stringify(this.stepInfo));
    this.steps.push(this.stepInfo);
    console.info("Complete test steps : " + JSON.stringify(this.testcase.steps));
    this.stepInfo.stepName = null;
    this.stepInfo.stepColor = null;
},

However, I have found out that when i push the first item , it is getting added to the array correctly, but when I push a second stepInfo object to the steps array , the second item is added, but it is also replacing the first item- which basically means that there are duplicates of the second item.

Console output follows:

test steps : {"stepName":"Step1 ","stepColor":"Error"}
app.js:15859 Complete test steps : [{"stepName":"Step1 ","stepColor":"Error"}]
app.js:15857 test steps : {"stepName":"Step 2","stepColor":"Default"}
app.js:15859 Complete test steps : [{"stepName":"Step 2","stepColor":"Default"},{"stepName":"Step 2","stepColor":"Default"}]
app.js:6345 [Vue warn]: Duplicate value found in v-for="step in testcase.steps": {"stepName":"Step 2","stepColor":"Default"}. Use track-by="$index" if you are expecting duplicate values. (found in component: <new-testcase>)warn @ app.js:6345vFor.warnDuplicate @ app.js:9917getCachedFrag @ app.js:9731diff @ app.js:9412update @ app.js:9368_update @ app.js:13663Watcher.run @ app.js:8666runBatcherQueue @ app.js:8397flushBatcherQueue @ app.js:8367nextTickHandler @ app.js:5771

Can you please let me know what I might be doing wrong here ?

Thanks

0 likes
2 replies
kfirba's avatar
kfirba
Best Answer
Level 50

@gj1118 When you are pushing an object, it's gonna push it as reference. You just need to make sure you clone the current object before you push it:

addStepToTask : function() {
    let clone = {...this.stepInfo};
    // if you don't have ES2015 transformer such as babel, you may need to clone it the old way:
    // let clone = (JSON.parse(JSON.stringify(this.stepInfo)));

    this.steps.push(clone);

    this.stepInfo.stepName = null;
    this.stepInfo.stepColor = null;
},

Do note that I did a shallow copy of the object here. If you ever find yourself having a nested object, you may want to look into a deep-copy method.

1 like

Please or to participate in this conversation.