Datsik
Datsik

Reputation: 14824

Function with forEach returns undefined even with return statement

I'm just making a function for checking a value of something in my object array, but for some reason it keeps returning undefined. Why is that?

Demo: http://jsfiddle.net/cNYwz/1/

var data = [{
    "Key": "1111-1111-1111",
        "Email": "[email protected]"
}, {
    "Key": "2222-2222-2222",
        "Email": "[email protected]"
}];


function getByKey(key) {    
    data.forEach(function (i, val) {
        if (data[val].Key === key) {
            return data[val].Key;
        } else {
            return "Couldn't find";
        }
    });
}

var asd = getByKey('1111-1111-1111');
console.log(asd);

Upvotes: 22

Views: 19832

Answers (5)

HBP
HBP

Reputation: 16043

Your function getByKey has no return statement. The two returns are for the anonymous function used by forEach.

Upvotes: 4

user663031
user663031

Reputation:

In addition to the ideas in the other answers, you're better off using Array.prototype.some, rather than forEach. That will let you stop when you find the first match:

function getByKey(key) {    
    var found = null;
    data.some(function (val) {
        if (val.Key === key) {
            found = val;
            return true; //stop iterating
        }
    });
    return found;
}

You might also consider using filter, which can return an array containing just the objects where key matches:

function filter_array_by_key(key){
    return data.filter(function(v){
        return v.Key===key;
    };
}

To get the first matching object, you can then use filter_array_by_key(key)[0], which will yield undefined if there was no match.

Upvotes: 1

Albert Xing
Albert Xing

Reputation: 5788

Try storing the positive result as a variable, and then returning that variable (or a "Couldn't find" in case nothing is written) at the end of the function after the forEach loop.

function getByKey(key) {    
    var result;

    data.forEach(function (val, i) {
        if (data[val].Key === key) {
            result =  data[val].Key;
        }
    });

    return result || "Couldn't find";
}

Upvotes: 1

Denys Séguret
Denys Séguret

Reputation: 382264

In your function, you're returning from the function passed to forEach, not from getByKey.

You could adapt it like this :

function getByKey(key) {    
    var found = null;
    data.forEach(function (val) {
        if (val.Key === key) {
            found = val;
        }
    });
    return found;
}

But this would iterate over all elements, even if the item is immediately found. That's why you'd better use a simple for loop :

function getByKey(key) {    
    for (var i=0; i<data.length; i++) {
         if (data[i].Key === key) {
            return data[i];
        }
    }
}

Note that I also adapted your code to return the value, not the key. I suppose that was the intent. You might also have been confused with another iteration function : the first argument passed to the callback you give to forEach is the element of the array.

Upvotes: 34

elclanrs
elclanrs

Reputation: 94121

You're not returning anything to the outer scope, try this alternative:

function getByKey(key) {    
  var result = data.filter(function (i, val) {
    return data[val].Key == key;
  });
  return result.length ? result : 'Not found';
}

Upvotes: 1

Related Questions