0
var matches = $.grep($.trolley, function(element){ 
    if ((element.id == grocery.id) && (element.dimensions == grocery.dimensions)) {
        console.log('t'); 
    } else { 
        console.log('f'); 
    } 
});

So I have say 3 items. id 1 dimensions 4, id 2 dimensions 8, id 2 dimensions 8

I want to find the item that isn't in the array, but as soon as it matches an item in the array that already has that id, it returns a match... Even though the dimensions differ :(

http://jsfiddle.net/justrealmilk/6SSKj/

Tom Chapman
  • 433
  • 7
  • 15

1 Answers1

2

The filter function needs to return true or false depending on whether the test succeeds (actually, only the true case is required, but doing both is cleaner, IMHO):

var matches = $.grep($.trolley, function(element){ 
    if ((element.id == grocery.id) && (element.dimensions == grocery.dimensions)) {
        console.log('t'); 
        return true;
    } else { 
        console.log('f');
        return false;
    } 
});

Since you weren't returning anything, it implicitly returns undefined, which should have been resulting in an empty matches. I'm not sure why you were getting anything, let alone just the first matching id.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • It is writing 't' to console even when false, still :( – Tom Chapman Jun 13 '13 at 16:42
  • Try doing `console.log('t', element, grocery);`, maybe these things don't contain what you think they contain. – Barmar Jun 13 '13 at 16:44
  • Don't see where this is on that site. Can you make a SSCE in a fiddle? – Barmar Jun 13 '13 at 17:06
  • Here's the problem: Every time you do `grocery = $(this).data('post')` it's returning the same object, not a new copy. That object, not a copy, was also pushed onto `$.trolley`. So when you do `grocery.dimensions = $('select').find(":selected").text();` you're modifying the object that's in `$.trolley`. So the dimensions match because they're the same object. – Barmar Jun 13 '13 at 18:20
  • I'm very confused. I thought I was grabbing the data from the button, adjusting value of that new object based on a string from the page, and then comparing it with $.trolley – Tom Chapman Jun 13 '13 at 18:26
  • jQuery is pulling a trick on you. It emulates its original definition of `.data()` as associating real objects with DOM elements. So it only creates a new object from the `data-post` attribute the first time, then it reuses that object from then on. Use `$.parseJSON($(this).attr('data-post'))` to get a new object each time. – Barmar Jun 13 '13 at 18:43
  • I've tried and tried to make this work beyond the example but it keeps returning null, possibly because it's an object, not a string? I don't know how to write what I've written any other way unfortunately... After reading some API docs, I gave .removeData() a go but it blew up in my face also. Is there any other way to resolve the internal cache issue? – Tom Chapman Jun 13 '13 at 20:59
  • Didn't my `$.parseJSON` suggestion work? Or see http://stackoverflow.com/questions/122102/most-efficient-way-to-clone-an-object for a way to clone an object in jQuery. – Barmar Jun 13 '13 at 21:11
  • I meant I tried and tried with your suggestion... I don't understand why I'd want to clone an object – Tom Chapman Jun 13 '13 at 21:21
  • The reason to clone the object is so that the object you push on `$.trolley` is not the same object that you pull out of `$(this).data('post')`, so modifying the latter doesn't also modify the former. See http://jsfiddle.net/6SSKj/2/ – Barmar Jun 13 '13 at 22:43