0

I have an object called Category which uses a method to iterate over an array of products (Product) and return an instance which meets the this.name === query condition:

function Category(products){
  this.products = products; 
  this.findProductByName = function(query){
    $(this.products).each(function(){
      return this.name === query; 
    }
  }
}

My Product (just in case):

function Product(name){
  this.name = name;
}

I then create an instance of Category with products:

var $someCategory = new Category(
   [
      new Product('foo'),
      new Product('bar')
   ]
)`

and when I call:

$someCategory.findProductByName('foo'); // 'undefined'

even though:

...
this.findProductByName = function(query){
  $(this.products).each(function(){
    console.log(this.name === query); // returns 'true'
  }
}
...

What do I do to return an object when this.name === query is met?

5
  • 2
    The $.each() mechanism ignores the returned values (mostly). What is it that you expect it to do? Commented Jun 1, 2016 at 0:32
  • 1
    use [].filter() and [].map() instead of each() Commented Jun 1, 2016 at 0:34
  • @Pointy return the correct Product instance when the conditional is met, so that I can search for products within $someCategory by name. What do you mean by "ignores the returned values"? Commented Jun 1, 2016 at 0:34
  • The return from inside the $.each() callback only returns from that function; it doesn't return from your findProductByName function. Commented Jun 1, 2016 at 0:36
  • @Pointy ahhhhhhh, makes sense. Thanks! Commented Jun 1, 2016 at 0:39

2 Answers 2

2

Do you need to use jQuery? Can you instead use the array filter method...

function Category(products){
  this.products = products; 
  this.findProductByName = function(query){
    return this.products.filter(function(item){
      return item.name === query; 
    });
  };
}
Sign up to request clarification or add additional context in comments.

Comments

1

You need to use a traditional loop with a return (or map/reduce) to have your function return the matched result. The each function performs an operation on each element in the array, it, won't perform filtering, and ignores the returned value.

Try this:

this.findProductByName = function(query) {
  for (var i = 0; i < this.products.length; i++) {
    if (this.products[i].name === query)
    {
      return this.products[i];
    }
  }
}

Also FYI, It's normal to pass arguments into the each() function which identify the current element being iterated over when using This helps eliminate the scope issue for 'this'

$(this.products).each(function( index, value ) {
  alert( index + ": " + value );
});

3 Comments

Nice! Thanks! Question: so why use each at all when the for loop already handles the iteration and returns vals?
It's syntactic niceness for when you explicitly want to perform an operation on each item in the array, i.e. adding a prefix to the name property: $(this.products).each(function(i,el){el.name = 'My ' + el.name;});
Also some people just love jquery over native javascript.

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.