0

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?

1
  • I don't think your subFilter function is doing what you think it's doing, I would check the value of i after it's first assignment if I were you. Also, no matter what, subFilter will never be === false so the if statements will always pass even if they shouldn't Commented Jan 1, 2016 at 15:48

4 Answers 4

3

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;
}
Sign up to request clarification or add additional context in comments.

Comments

0

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

Comments

0

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 = []

3 Comments

i should come back as either false or an integer.
My intended purpose for this function was to return the index of the object that already exists for purpose of updating, or false if the object doesn't exist.
Then you should try the first one i mentioned. And you can prepend a if(model[i] != null) to prevent Cannot set property .. of undefined errors.
0

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/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.