Finally i'm writing a question on my own because i read other question here but still don't understand why my code doesn't work. Perhaps someone can explain me what i got wrong?
The Code runs till the search for the name "Joe", Then it say par2 is not defined...Why? In the check after the search function i can clearly see that both parameters par1 and par2 are returned...
var friends = {};
friends.bill = {
firstName: "Bill",
lastName: "Gates",
number: "(206) 555-5555",
address: ['One Microsoft Way', 'Redmond', 'WA', '98052']
};
friends.steve = {
firstName: "Steve",
lastName: "Jobs",
number: "(408) 555-5555",
address: ['1 Infinite Loop', 'Cupertino', 'CA', '95014']
};
function list(obj) {
for (var prop in obj) {
console.log(prop);
}
};
function bettersearch(name2) {
var sna = name2
for (var prop in friends) {
if (friends[prop].firstName === name2) {
// console.log("Value found :",friends[prop]);
return {
par1: friends[prop],
par2: sna
}
}
}
};
// Test if the variables are returned
var test = bettersearch("Bill")
console.log("\n\n",test);
console.log("\n\n",test.par1);
console.log("\n\n",test.par2);
//Formatting function for a nice Output
function format(obj) {
if (obj) {
var result = "";
result += "\nName: " + obj.par1.firstName + " " + obj.lastName;
result += "\nNumber: " + obj.par1.number;
result += "\nAddress: " + obj.par1.address.join(', ');
console.log(result);
} else {
console.log("\nDer Name", obj.par2, "wurde nicht gefunden");
}
}
//Call the functions
format(bettersearch("Bill"));
format(bettersearch("Steve"));
format(bettersearch("Joe"));
Then it say par2 is not defined...
No, it doesn't. It says something like Cannot convert 'obj' to object or Cannot access 'par2' on undefined.
Why?
Because your bettersearch function does not return anything when it doesn't find the name. In your format function you explicitly check for the existence of obj, but despite it being undefined you try to access obj.par2.
I think you are looking for
function bettersearch(name) {
for (var prop in friends)
if (friends[prop].firstName === name)
return {
friend: friends[prop],
name: name
};
return {
name: name
}; // always return a result object
}
function format(obj) {
if (obj.friend) {
var result = "";
result += "\nName: " + obj.friend.firstName + " " + obj.friend.lastName;
result += "\nNumber: " + obj.friend.number;
result += "\nAddress: " + obj.friend.address.join(', ');
console.log(result);
} else {
console.log("\nDer Name", obj.name, "wurde nicht gefunden");
}
}
This might be a much better way to structure your data and write your search function
var friends = [
{
firstName: "Bill",
lastName: "Gates",
number: "(206) 555-5555",
address: ['One Microsoft Way', 'Redmond', 'WA', '98052']
},
{
firstName: "Steve",
lastName: "Jobs",
number: "(408) 555-5555",
address: ['1 Infinite Loop', 'Cupertino', 'CA', '95014']
}
];
function searchFriends(firstName) {
return friends.filter(function(f) {
return f.firstName === firstName;
});
}
console.log(searchFriends("Bill"));
//=> [{"firstName":"Bill","lastName":"Gates","number":"(206) 555-5555","address":["One Microsoft Way","Redmond","WA","98052"]}]
console.log(searchFriends("Steve"));
//=> [{"firstName":"Steve","lastName":"Jobs","number":"(408) 555-5555","address":["1 Infinite Loop","Cupertino","CA","95014"]}]
console.log(searchFriends("Joe"));
//=> []
I make this suggestion because in your code, it'd be very easily to have duplicates.
E.g., what about John Smith and John Smyth? Both would use friends.john...
If you want the search result to return the query and the matches
function searchFriends(firstName) {
return {
search: firstName,
result: friends.filter(function(f) {
return f.firstName === firstName;
})
};
}
Use it the same way
console.log(searchFriends("Steve"));
// {
// search: "Steve",
// result: [{"firstName":"Steve","lastName":"Jobs","number":"(408) 555-5555","address":["1 Infinite Loop","Cupertino","CA","95014"]}]
// }
console.log(searchFriends("Joe"));
// {
// search: "Joe",
// result: []
// }
The actual error is
"TypeError: Cannot read property 'par2' of undefined
Your error is in your console.log() line where if(obj) returns false (meaning there is no object - it's actually undefined):
console.log("\nDer Name", obj.par2, "wurde nicht gefunden");
Remove that line altogether.
Related
I want to check a bunch of variables for falsy values.
Instead of writing a very long if statement, e.g.:
if (!userData.email || !userData.lastName || ! userData.firstName etc...
I wanted to put these values in an array and simply check the array, e.g.:
var detailsConditionsArr = [
userData.firstName,
userData.lastName,
userData.email,
userData.phone,
userData.address,
userData.mailAddress,
]
if (detailsConditionsArr.indexOf(false) === 1) {
console.log("Found a falsy");
}
But the above doesn't work (if statement never fires).
The values could be false, null or ''.
Is there a way to check these from the array?
Ideal use case for Array#some
Check for falsy value in the iteration, if the test succeeds, true will be returned.
var A = ["Name", ""];
var B = ["Name", "30"];
var C = ["Name", "30", null];
if (A.some(el => !el)) {
console.log("Found a falsy in A");
}
if (B.some(el => !el)) {
console.log("Found a falsy in B");
}
if (C.some(el => !el)) {
console.log("Found a falsy in C");
}
You can use the key names you want to check as an array, then do the check like this:
const userData = { email: '', lastName: '', firstName: '' };
const hasFalsy = ['email', 'lastName', 'firstName'].some(k => !Boolean(userData[k]));
if (hasFalsy) {
console.log('found a falsy');
}
You can use reduce to return a single value from the array like so:
var detailsConditionsArr = [
userData.firstName,
userData.lastName,
userData.email,
userData.phone,
userData.address,
userData.mailAddress,
]
if (detailsConditionsArr.reduce((carry, el)=> el ? carry : true, false)) {
console.log("Found a falsy");
}
You can loop the list of properties and then check if any is falsy :
const userData = {
firstName : 'John',
lastName : 'Doe',
email : null,
phone : 42,
address : 'Hello',
mailAddress : 'world'
};
function HasObjectAnyFalsyValues(obj)
{
for (let prop in obj)
{
if (Object.prototype.hasOwnProperty.call(obj, prop)
&& !obj[prop]) { // <-- check for falsy
return true;
}
}
return false;
}
console.log('The object has ' + (!HasObjectAnyFalsyValues(userData) ? 'no ' : '') + 'falsy values');
This will check all properties. If you want to list specific properties instead, use one of the other answers posted
You can use some method.
var detailsConditionsArr = [
"test",
12,
false,
"s",
"sd",
"test",
]
if (detailsConditionsArr.some(x => !x)) {
console.log("Found a falsy");
}
// or
//if (detailsConditionsArr.some(x => !Boolean(x))) {
// console.log("Found a falsy");
//}
Using some is a clean way for doing this job.
The Array.prototype.some() method tests whether at least one element in the array passes the test implemented by the provided function (in your case, falsy value).
const userData = {};
userData.firstName = "dd";
userData.lastName = false;
userData.email = 0;
userData.phone = 123;
userData.address = "aad";
userData.mailAddress = "dff";
const detailsConditionsArr = [
userData.firstName,
userData.lastName,
userData.email,
userData.phone,
userData.address,
userData.mailAddress,
]
const detailsConditionsArr2 = [true, 1, "fff"];
const doesHaveFalsy = obj => obj.some(x => !x);
if (doesHaveFalsy(detailsConditionsArr)) {
console.log("detailsConditionsArr Found a falsy");
}
if (doesHaveFalsy(detailsConditionsArr2)) {
console.log("detailsConditionsArr2 Found a falsy");
}
More about some - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some
1) I've got an array of objects, called employees.
2) I'm trying to find the highest paid employee in the array.
3) I'm using Javascript's reduce function (inside function findHighestPaid) to do so.
4) Running findHighestPaid(employees) returns "undefined" when I expected it to return the object that has property name: Abelard.
Here's my code.
const employees = [
{
name: "Aziz",
salary: 17050,
},
{
name: "Angela",
salary: 17060,
},
{
name: "Abelard",
salary: 17070,
},
];
function findHighestPaid(arrayOfObjects) {
let myObject = {
name: "pretendEmployee",
salary: 17040,
};
arrayOfObjects.reduce(myFunction, myObject);
function myFunction(acc, item) {
let personSalary = item.salary;
let accSalary = acc.salary;
if (Math.sign(personSalary - accSalary) > 0) {
console.log(`returning object for ${item.name}`);
return item;
} else {
console.log(`returning object for ${acc.name}`);
return acc;
}
} // end myFunction
}
When I run findHighestPaid(employees) and look in console I see :
returning object for Aziz // (as I expected)
returning object for Angela // (as I expected)
returning object for Abelard // (as I expected)
undefined // (oh oh!!!)
Why does the reduce function return "undefined"?
the undefined that's being printed at the end is the return value of findHighestPaid() function that you run.
since you're not returning anything it's returning undefined.
if your goal is to see the return value of reduce() add a return statement to the function like this:
const employees = [
{
name: "Aziz",
salary: 17050,
},
{
name: "Angela",
salary: 17060,
},
{
name: "Abelard",
salary: 17070,
},
];
function findHighestPaid(arrayOfObjects) {
let myObject = {
name: "pretendEmployee",
salary: 17040,
};
return arrayOfObjects.reduce(myFunction, myObject);
function myFunction(acc, item) {
let personSalary = item.salary;
let accSalary = acc.salary;
if (Math.sign(personSalary - accSalary) > 0) {
console.log(`returning object for ${item.name}`);
return item;
} else {
console.log(`returning object for ${acc.name}`);
return acc;
}
} // end myFunction
}
console.log(findHighestPaid(employees));
Your code is working perfectly although you don't need Math.sign at all, just return the result:
const employees = [
{
name: "Aziz",
salary: 17050,
},
{
name: "Angela",
salary: 17080,
},
{
name: "Abelard",
salary: 17070,
},
];
function findHighestPaid(arrayOfObjects) {
let myObject = {
name: "pretendEmployee",
salary: 17040,
};
return arrayOfObjects.reduce(myFunction, myObject);
function myFunction(acc, item) {
let personSalary = item.salary;
let accSalary = acc.salary;
if (personSalary - accSalary > 0) {
console.log(`returning object for ${item.name}`);
return item;
} else {
console.log(`returning object for ${acc.name}`);
return acc;
}
} // end myFunction
}
console.log('Highest paid', findHighestPaid(employees));
you just have to put it like this
function findHighestPaid(arrayOfObjects) {
return arrayOfObjects.reduce((prev, curr) => {
if(!prev) {
return curr;
}
return curr.salary > prev.salary ? curr : prev;
}, null);
}
const highestPaidEmployee = findHighestPaid(employees);
I facing an issue in javascript, i want to remove undefined value from object
Expected Output
Without undefined value ni array.
var result = [
undefined,
undefined,
{
group: '1042000018356',
email: 'xyz#desk.com'
},
{
group: '1042000098595',
email: 'abc#desk.com'
}
]
// This my logic:
result = result.map(function(index){
for (var key in array) { // Looping
if( index == key ){
var group = array[key]; // Group id
var email = key; // Email
return {group , email};
}
}
});
console.log("result", result);
How can i remove undefined value from Object
can anyone help me please?
You can just do a filter and pass on a boolean constructor which will ensure you remove all the null and undefined values from the result array
var result = [
undefined,
undefined,
{
group: '1042000018356',
email: 'xyz#desk.com'
},
{
group: '1042000098595',
email: 'abc#desk.com'
}
]
result = result.filter(Boolean);
console.log(result);
Another way to do it with simple filter() to remove undefined, here the filter internally turns the return value of the callback to Boolean which is similar to Boolean constructor i.e filter(Boolean)
result = [
undefined,
undefined,
{
group: '1042000018356',
email: 'xyz#desk.com'
},
{
group: '1042000098595',
email: 'abc#desk.com'
}
]
result = result.filter(el=>el)
console.log(result);
Try this example :
var newarray = [
undefined,
undefined,
{
group: '1042000018356',
email: 'xyz#desk.com'
},
{
group: '1042000098595',
email: 'abc#desk.com'
}
];
var R = [];
newarray.map(function(item, index , myarray){
// console.log("item -> ", item);
if( typeof item === 'undefined') {
// console.log("undefined detected!");
} else {
R.push(item);
}
});
console.log("result -> ", R);
I'm trying to test my function with mocha + nyc for cheching coverage.
This is function to test:
function TypeCompare(Obj){
Obj.forEach(function (el){
el.Age = StringToNumber(el.Age);
el.Name = isValidString(el.Name);
el.Surname = isValidString(el.Surname);
el.Mail = isEmail(el.Mail);
el.DateofReg = StringToDate(el.DateofReg);
el.Phone = isPhone(el.Phone);
el.Time = StringToTime(el.Time);
if(el.Age == "Age error" || el.Name == "Name/Sname error" || el.Surname == "Name/Sname error" || el.DateofReg == "Date error" || el.Time == "Time error" ||el.Mail == "Email error" || el.Phone == "Phone error"){
invalid_types.push(el);
} else {
valid_types.push(el);
}
});
RecordToDB(valid_types);
RecordToCSV(invalid_types);
}
The function getting array of objects check objects with other function for valid and push valid objects to valid_types and invalid to invalid_types.
This is my testing function:
describe('Testing function TypeCompare which getting arr[objects] on input
check arr for valid and invalid objects', function () {
it('should return [valid_obj] and [] if all objects is valid', function ()
{
var arr = [{Age: '20', Name: 'Kiryl', Surname: 'Kazushchyk', Mail: 'kastys1#yandex.ru', DateofReg: '10-20-2015',
Phone: '+375257794915', Time: '10:44'},
{Age: 'fgh', Name: 'Kiryl', Surname: 'Kazushchyk', Mail: 'kastys1#yandex.ru', DateofReg: '10-20-2015',
Phone: '+375257794915', Time: '10:44'}];
app.TypeCompare(arr);
// console.log(TypeCompare.valid_types);
// console.log(TypeCompare.invalid_types);
var expected_valid = [{Age: '20', Name: 'Kiryl', Surname: 'Kazushchyk', Mail: 'kastys1#yandex.ru', DateofReg: '2015-10-20',
Phone: '+375257794915', Time: '10:44:00'}];
var expected_invalid = [{Age: 'Age error', Name: 'Kiryl', Surname: 'Kazushchyk', Mail: 'kastys1#yandex.ru', DateofReg: '2015-10-20',
Phone: '+375257794915', Time: '10:44:00'}];
assert(app.invalid_types[0].Age === expected_invalid[0].Age);
assert(app.valid_types[0].Age === expected_valid[0].Age);
});
});
I'm export this:
module.exports.TypeCompare =TypeCompare;
module.exports.valid_types = valid_types;
module.exports.invalid_types = invalid_types;
The test is passed ok, but i don't recive any information about summary:
test result without coverage
If i test my other functions everything is okay:test result other functions
Can someone tell me what is the problem?
Solved. The problem was in functions which called with TypeCompare
Given an object that has a "firstName" property and a "lastName" property, "addFullNameProperty" returns a "fullName" property whose value is a string with the first name and last name separated by a space.
var person = {
firstName: 'Jade',
lastName: 'Smith'
};
addFullNameProperty(person);
console.log(person.fullName); // --> 'Jade Smith'
my code :
function addFullNameProperty(obj) {
// your code here
obj[fullName] = obj.firstName + obj.lastName;
}
Just simple set:
obj.fullName instead of obj[fullName]
Or
obj['fullName']
Because fullName in your code is undefined variable. So JS alert error.
Either use obj.fullName or obj['fullName']
But a more correct solution would be
function addFullNameProperty(obj) {
// your code here
Object.defineProperty(obj, 'fullName', {
get: function(){
return this.firstName + ' ' + this.lastName;
},
configurable:false
});
}
var person = {
firstName: 'Jade',
lastName: 'Smith'
};
addFullNameProperty(person);
console.log(person.fullName); // --> 'Jade Smith'
person.firstName = "Mike";
console.log(person.fullName); // --> 'Mike Smith'
This way your object will always return the correct fullName.
If you want to add the space into the name, you will need to do string interpolation, like so:
`${obj.firstName} ${obj.lastName}`
and complement this with Gaby's answer about switching to dot notation, obj.fullName
Add new property to an existing object:
const person = {
firstName: 'Jade',
lastName: 'Smith'
};
person.fullName = `${person.firstName} ${person.lastName}`;
same as:
person['fullName'] = `${person.firstName} ${person.lastName}`;
or using method:
const person = {
firstName: 'Jade',
lastName: 'Smith',
fullName(){
return `${this.firstName} ${this.lastName}`;
}
};
person.fullName(); // Jade Smith
You can also use defineProperty
Try this
return obj.fullName = obj.firstName + " " + obj.lastName