imperium2335
imperium2335

Reputation: 24122

Insert or update object in JavaScript

I am trying to build an object in JavaScript, but have properties updated or created based on if a product id already exists. I have:

var model = [];

$('.glyphicon-plus').click(function() {
    var product_id = $('#productSelect').val();
    var size_id = $('#sizeSelect').val();
    var colour_id = $('#colourSelect').val();
    var quantity = $('#quantity').val();
    if (i = subFilter(model, "product_id", product_id) !== false) {
        if (i = subFilter(model, "size_id", size_id) !== false) {
            if (i = subFilter(model, "colour_id", colour_id) !== false) {
                console.log(model);
                model.i.quantity = quantity;
            }
        }
    }
    model.push({
        product_id: product_id,
        size_id: size_id,
        colour_id: colour_id,
        quantity: quantity
    });
    subFilter(model, "product_id", product_id);
    console.log(model)
});

function subFilter(object, paramName, paramValue) {
    $.each(object, function(i, v) {
        if (v[paramName] == paramValue) {
            return i;
        }
    });
}

But I am getting:

Uncaught TypeError: Cannot set property 'quantity' of undefined

How can I build up this object properly, inserting a new "record" or updating if it already exists?

Upvotes: 0

Views: 2510

Answers (4)

wui
wui

Reputation: 410

I think you should create dynamic array according to product id,size and color so I shortened your code like this ,

$(document).ready(function(){
     var model = [];
     var formattedModel=[];


  $('.glyphicon-plus').click(function() {
    var product_id = $('#productSelect').val();
    var size_id = $('#sizeSelect').val();
    var colour_id = $('#colourSelect').val();
    var quantity = $('#quantity').val();

    if(!model.hasOwnProperty(product_id)) model[product_id]=[];
    if(!model[product_id].hasOwnProperty(size_id)) model[product_id][size_id] = [];

    model[product_id][size_id][colour_id]= quantity;
   console.log(model);
   //iterate through keys
   for (var p in model){
        var formattedModel=[];
        if (model.hasOwnProperty(p)) {

         for(var s in model[p])
         if (model[p].hasOwnProperty(s)) {
            for(var c in model[p][s])
            {
             if(model[p][s].hasOwnProperty(c)) {
              formattedModel.push({
              "product_id":p,
              "size_id":s,
              "colour_id":c,
              "quantity":model[p][s][c]
              });
             }
            }
         }
    }
    }

    console.log(formattedModel); // your model structure


    });


 });

and it will either add product or update product and you can iterate through the array afterwards easily.

working fiddle https://jsfiddle.net/kodedsoft/hvdL4da5/1/

Upvotes: 0

Tushar
Tushar

Reputation: 87203

Change

model.i.quantity = quantity;

to

model[i].quantity = quantity;

To access dynamic properties of object, use array notation.

.i will search for the key 'i' inside the object model whereas in model[i] the value of i will be replaced first and then the key will be searched in model object.


Update:

The code in Question contain many errors. Try following code.

var model = [];

$('.glyphicon-plus').click(function () {
    var product_id = $('#productSelect').val(),
        size_id = $('#sizeSelect').val(),
        colour_id = $('#colourSelect').val(),
        quantity = $('#quantity').val();

    // Get index of the element where all the fields matches
    var index = getObjectIndex(model, product_id, size_id, colour_id);

    // If object found in the array
    if(index !== false) {
        // Update the quantity in the same element
        model[index].quantity = quantity;
    } else {
        // Add the element in the array
        model.push({
            product_id: product_id,
            size_id: size_id,
            colour_id: colour_id,
            quantity: quantity
        });
    }
});

// Currently the function is Static, but it can be changed to dynamic
// by using nested loop and a flag to store the match status
function getObjectIndex(arr, product_id, size_id, colour_id) {
    // Loop over array to find the matching element/object
    for(var i = 0; i < arr.length; i++) {
        var obj = arr[i];
        if(obj.product_id === product_id && obj.size_id === size_id && obj.colour_id === colour_id) {
            // When all key-value matches return the array index
            return i;
        }
    }

    // When no match found, return false
    return false;
}

Upvotes: 3

abeyaz
abeyaz

Reputation: 3164

If your i will always be an integer, you should use model[parseInt(i)].quantity = quantity.

If it is not, you need to define model var model = {}, NOT var model = []

Upvotes: 0

nihar jyoti sarma
nihar jyoti sarma

Reputation: 541

i think issue is in empty model array.due to that model[i] is displaying as undefined.so,it's throwing the below error.

Cannot set property 'quantity' of undefined

Upvotes: 0

Related Questions