Javascript Can't catch an error inside map function - javascript

let's say I have a usersList like this:
var usersList = [
{ firstName : 'Adam', lastName: 'Yousif', age: 23 },
{ firstName : 'Mohamed', lastName: 'Ali' },
{ firstName : 'Mona', lastName: 'Ahmed', age: 19 },
];
Now I want to call map function on usersList and return a modified list like so :
var returnList = usersList.map((_user) => {
var _age;
try {
_age = _user.age;
} catch (error) {
console.log('I caught error here : ', error); // <-- not printed
_age = 'FAILSAFE-VAULE'; // <-- not set
}
var obj = {
firstName: _user.firstName,
lastName: _user.lastName,
age: _age
}
return obj;
});
I have a try-catch block inside the map function, the purpose if it is to replace the undefined property "age" of the second user with a 'FAILSAFE-VALUE'. but it doesn't work as should.
console.log(returnList);
// prints
// [
// { firstName: 'Adam', lastName: 'Yousif', age: 23 },
// { firstName: 'Mohamed', lastName: 'Ali', age: undefined }, <-- not what I want
// { firstName: 'Mona', lastName: 'Ahmed', age: 19 }
// ]
How to catch an error inside javascript map function?
Thank you

You don't need to do try catch for that:
usersList.map((_user) => {
return {
firstName: _user.firstName,
lastName: _user.lastName,
age: _user.age || 'FAILSAFE-VAULE'
};
});

That's because nothing is thrown (the age is just undefined). If you want information about this "error" during the map-operation, the first part of the snippet may be an idea. If you really want to use try - catch, use the second part (it throws 'manually' when _user.age is undefined). The latter demonstrates (by the way) that try - catch does work within a map-operation.
const usersList = [{
firstName: 'Adam',
lastName: 'Yousif',
age: 23
},
{
firstName: 'Mohamed',
lastName: 'Ali'
},
{
firstName: 'Mona',
lastName: 'Ahmed',
age: 19
},
];
const getFailSafe = user => {
if (!user.age) {
console.log(`Note: user.age not available for ${user.firstName} ${user.lastName}`);
return `FAILSAFE-VAULE`;
}
return user.age;
};
// 1. use a warning if .age not present
const returnList = usersList
.map((_user) => ({
firstName: _user.firstName,
lastName: _user.lastName,
age: getFailSafe(_user)
})
);
// 2. throw an Error if .age not present
const returnListWithError = usersList
.map((_user) => {
let retVal = {
firstName: _user.firstName,
lastName: _user.lastName,
}
try {
retVal.age = _user.age ||
(() => {
throw new Error(`ERROR: user.age not available for ${
_user.firstName} ${_user.lastName} (will continue with 'FAILSAFE-VAULE')`);
})();
} catch (err) {
console.log(`${err.message}`);
retVal.age = `FAILSAFE-VAULE`;
}
return retVal;
});
console.log(returnList.find(v => isNaN(v.age)));
console.log(returnListWithError.find(v => isNaN(v.age)));
.as-console-wrapper { top: 0; max-height: 100% !important; }

try...catch block would not work there as after accessing a value which does not exist you just receive an undefined
just do it next way:
var returnList = usersList.map((_user) => {
return {
firstName: _user.firstName,
lastName: _user.lastName,
age: _user.age ? _user.age : 'FAILSAFE-VAULE'
}
});

Related

Compare and get difference from two object for patch api request in react js?

i m having two objects previous and new one, i trying to compare and get difference for those objects, send to as patch payload from patch api,
compare each properties in object if any of the property has any difference i want all those difference in new object as payload
How can i achieve this please help me find the solution?
Is there any lodash method for this solution?
let obj = {
Name: "Ajmal",
age: 25,
email: "ajmaln#gmail.com",
contact: [12345678, 987654321],
address: {
houseName: "ABC",
street: "XYZ",
pin: 67891
}
}
let obj2 = {
Name: "Ajmal",
age: 25,
email: "something#gmail.com",
contact: [12345678, 11111111],
address: {
houseName: "ABC",
street: "XYZ",
pin: 111
}
}
result payload i m expecting would look like
let payload = {
email: "something#gmail.com",
contact: [12345678, 11111111],
address: {
pin: 111
}
}
Mista NewbeedRecursion to your service:
const compare = (obj1, obj2) => {
const keys = Object.keys(obj1);
const payload = {};
keys.forEach((el) => {
const first = obj1[el];
const second = obj2[el];
let check;
if (first !== second) {
if (first instanceof Object && !(first instanceof Array))
check = compare(first, second);
payload[el] = check || second;
}
});
return payload;
};
Here is a approach with immer that may guide you to a proper solution
This is not a generic approach but makes things easier by relying on immer
import produce, { applyPatches, enablePatches } from "immer";
import { difference } from "lodash";
// once in your app
enablePatches();
let obj = {
Name: "Ajmal",
age: 25,
email: "ajmaln#gmail.com",
contact: [12345678, 987654321],
address: {
houseName: "ABC",
street: "XYZ",
pin: 67891
}
};
let obj2 = {
Name: "Ajmal",
age: 25,
email: "something#gmail.com",
contact: [12345678, 11111111],
address: {
houseName: "ABC",
street: "XYZ",
pin: 111
}
};
Gettig the patch updates
let fork = { ...obj };
let changes = [];
const updatedItem = produce(
fork,
(draft) => {
// object specific updates
draft.Name = obj2.Name;
draft.age = obj2.age;
draft.email = obj2.email;
draft.address.houseName = obj2.address.houseName;
draft.address.street = obj2.address.street;
draft.address.pin = obj2.address.pin;
const originalContact = original(draft.contact);
const contactDiff = difference(obj2.contact, originalContact);
console.log("diff", contactDiff);
if (contactDiff?.length) {
draft.contact = contactDiff;
}
},
(patches) => {
changes.push(...patches);
}
);
//Problem here => default values need to be given to state
// so the default values need to be excluded from the patch
let state = { contact: [], address: {} };
const patch = applyPatches(state, changes);
console.log("patch", patch);
logs changes op
contact: Array(1)
0: 11111111
address: Object
pin: 111
email: "something#gmail.com"
Hope this helps you in some way
Cheers

Validate optional string with Yup?

I'm trying to validate a string with Yup:
const schema = object({
firstname: string().optional().nullable().notRequired().min(2),
});
The rules should be a string but can be null or empty, and if there is a value, then the length must be more than 2.
But for some reason, it's not working:
const shouldWorks = [
{ firstname: 'bla' },
{ firstname: '' }, <--- its failed here.. empty is okay (.notRequired)
{ firstname: null },
];
How do I change the schema to fit my rules?
stackblitz
import { object, string } from 'yup';
console.clear();
const shouldWorks = [
{ firstname: 'bla' },
{ firstname: '' },
{ firstname: null },
];
const shouldNotWork = [{ firstname: 'a' }];
const schema = object({
firstname: string().optional().nullable().notRequired().min(2),
});
shouldWorks.forEach((obj, i) => {
console.log(`test: ${i}`);
schema.validateSync(obj);
});
shouldNotWork.forEach((obj, i) => {
try {
schema.validateSync(obj);
console.log(`error test: ${i} failed`);
} catch (e) {
console.log(`error test: ${i} pass`);
}
});
You can use yup.lazy to lazily decide what validators to use based on the value:
const schema = object({
firstname: lazy((value) =>
value === ''
? string()
: string().optional().nullable().notRequired().min(2)
),
});
Stackblitz

How to remove an object from an array if it has the letter a?

I need to make a function that receives 2 parameters, the first one is an array of a list of users that must contain first name, last name and phone numbers, at least 3 of those users must start with the letter "a", the second parameter is a callback. You must process the array and delete all the users whose name starts with the letter "a". Then send the new processed array to the callback. The callback must show in console, the list of all the names, concatenating first and last name.
const users =
[{
name: 'Diego',
lastname: 'Garcia',
phone: '12343'
},
{
name: 'Camilo',
lastname: 'Garcia',
phone: '12343'
}, {
name: 'ana',
lastname: 'Rodriguez',
phone: '02343'
}, {
name: 'anastasia',
lastname: 'Zapata',
phone: '42343'
}, {
name: 'alejandra',
lastname: 'Perez',
phone: '52343'
}];
const operation2 = (list) => {
let x = [];
let callback = {};
callback = list.find(element => element.name.charAt(0) == 'a');
let l = list.indexOf(callback)
let g = list[l];
console.log(g)
if (callback) {
x = list.splice(l, 1)
} return list
}
console.log(operation2(users))
The code that I made does not work, it is not eliminating all the names that begin with "a", it only eliminates the first object of the array.
Array.find only finds the first match, you should probably filter out the elements you don't want:
const result = list.filter(element => element.name.charAt(0) !== 'a');
const users =
[{
name: 'Diego',
lastname: 'Garcia',
phone: '12343'
},
{
name: 'Camilo',
lastname: 'Garcia',
phone: '12343'
}, {
name: 'ana',
lastname: 'Rodriguez',
phone: '02343'
}, {
name: 'anastasia',
lastname: 'Zapata',
phone: '42343'
}, {
name: 'alejandra',
lastname: 'Perez',
phone: '52343'
}];
function func(list, callback) {
let users = list.filter(u => !u.name.toLowerCase().startsWith('a'));
callback(users)
}
func(users, (users) => {
console.log(users)
})

Function Traversing Through An Array of Json Object needs to return one object

So I am not the best at writing functions so I am having a hard time wrapping a head around this. So I am trying to create a function that traverses through array of objects, and stops once it reads the name that is given it must return the number of the that person.
const array = [{name: 'Ann', phone: '575.580.1400', role: 'Developer'},
{name: 'Ben', phone: '575.641.4041', role: 'Manager'},
{name: 'Clara', phone: '512.717.5690', role: 'Developer'}];
const getNumber = (person, book ) => {
for (var x of book ) {
if( x == person) {
return number;}
return ('Not found');
}
}
I know I am missing how to call in the number, but I just can't think of how to do it.
First you need to access the key inside the object and return ('Not found'); is not in the right place. Secondly use === instead of ==.In your code if the function will return in the fist iteration only. Because if you search for Clara and in the if condition Ann will not be equal to Clara so it will return Not Found and will not iterate the remaining array
const array = [{
name: 'Ann',
phone: '575.580.1400',
role: 'Developer'
},
{
name: 'Ben',
phone: '575.641.4041',
role: 'Manager'
},
{
name: 'Clara',
phone: '512.717.5690',
role: 'Developer'
}
];
const getNumber = (person, book) => {
for (var x of book) {
if (x.name === person) {
return x.phone;
}
}
return ('Not found');
}
console.log(getNumber('Clara', array))
Alternatively you can also use array methods like find or filter
const array = [{
name: 'Ann',
phone: '575.580.1400',
role: 'Developer'
},
{
name: 'Ben',
phone: '575.641.4041',
role: 'Manager'
},
{
name: 'Clara',
phone: '512.717.5690',
role: 'Developer'
}
];
const num = array.find(item => item.name === 'Clara').phone;
console.log(num)
Below code helps to iterate through a JSON object and print the required value. You can use the required conditions in IF and print the desired values accordingly.
var json = [{name: 'Ann', phone: '575.580.1400', role: 'Developer'},
{name: 'Ben', phone: '575.641.4041', role: 'Manager'},
{name: 'Clara', phone: '512.717.5690', role: 'Developer'}];
for (var key in json) {
if (json.hasOwnProperty(key)) {
if(json[key].name=='Ben')
console.log(json[key].phone);
}
}
Try this
I am using some instead of foreach or other loops. some() method executes the callback function once for each element present in the array until it finds the one where callback returns a truthy value.
const getNumber = (person, book ) => {
let pnumber;
book.some((item) => {
if(item.name.toLowerCase()===person.toLowerCase()){
pnumber = item.phone;
return true;
}
})
return pnumber ? pnumber: "Not Found" ;
}
you can call it this way
getNumber('clara',array)
"512.717.5690"
getNumber('ben1',array)
"Not Found"

check if data is already present in array of objects

I have the following data with me.
var Inputdata = {};
Inputdata.firstName = 'Raul'
Inputdata.lastName = 'Peters'
I want to check if the firstName and lastName (together) is already present in the array of objects. Can someone please let me know how to achieve this.
UserData: [0]
firstName: 'Raul'
lastName: 'Peters'
Id: '4'
[1]
firstName: 'Amil'
lastName: 'Rikia'
Id: '5'
[2]
firstName: 'Riya'
lastName: 'Pillai'
Id: '6'
[3]
firstName: 'Natasha'
lastName: 'Shacke'
Id: '6'
[4]
firstName: 'Eric'
lastName: 'Coles'
Id: '6'
As you can see, Raul Peters is present in the array of objects in one array. I want the output to be true in this case. If Raul and Peters were in different objects, the answer should be false as Raul and Peters are not in the same object. Can anyone please let me know how to achieve this
Just do an Array.some check:
let isPresent = UserData.some(user => user.firstName == 'Raul' && user.lastName == 'Peters')
Use Array.find
arr.find( function(e){
if(e.firstname == 'Raul' && e.lastname == 'Peters')
return e;
});
const inputData = {};
inputData.firstName = 'Raul';
inputData.lastName = 'Peters';
const userData = [
{
firstName: 'Raul',
lastName: 'Peters',
Id: '4'
},
{
firstName: 'Amil',
lastName: 'Rikia',
Id: '5'
},
{
firstName: 'Riya',
lastName: 'Pillai',
Id: '6'
},
{
firstName: 'Natasha',
lastName: 'Shacke',
Id: '6'
},
{
firstName: 'Eric',
lastName: 'Coles',
Id: '6'
}
];
This function receives 2 arguments: the userData array of objects and the inputData object. Then, it uses the Array.prototype.some() method to see if there is at least one entry within the userData array that is an object matching the inputData object.
function alreadyExists(userData, inputData) {
return userData.some(entry => entry['firstName'] === inputData['firstName'] && entry['lastName'] === inputData['lastName']);
};
console.log(alreadyExists(userData, inputData));
If you wanna use underscore or lodash you can use function _.some. Using internal variable you can get needle element.
var needle = false;
var has = _.some(UserData, function(v) {
return (v.firstName===Inputdata.firstName && v.lastName===Inputdata.lastName) ? needle = v : false;
});
console.log(has)
console.log(needle)

Categories

Resources