How to handle null values with lodash - javascript

This is simple json
{
home: 68
id: 1
name: "RL Conference Room"
nickname: null
setpoint: 32.34
sleep: 58
}
When I get empty key this lodash function works
_.get(room, 'keyName', 'whenKeyNotFound')
But as you can see above i am getting null value in nickname So I want to replace it with name but this doesn't work.
_.get(room, 'nickname', 'name')
Is there any function in lodash which does the trick?
Thank you!!!

In one level scenario and since (in your case) null is also an undesired result it seems you are better of without lodash and simply do this:
room.nickname || room.name
It would actually be shorter and achieve the same result in your case.
You could also do:
let name = _.defaultTo(room.nickname, room.name)
_.defaultTo to protects you from null, NaN and undefined
So in the case above you would get the obj.name but if you have nickname set you would get that.
In scenarios where you have a long path you can utilize _.isEmpty in a custom function like this:
const getOr = (obj, path, def) => {
var val = _.get(obj, path)
return _.isEmpty(val) ? def : val
}
This will handle your null as well as other scenarios as per _.isEmpty docs.
You can simply then use as:
getOr(room, 'nickname', room.name)
And you can nest it:
getOr(room, 'nickname', getOr(room, 'name', 'N/A'))

You can rely on the fact that null, undefined, etc. are falsy, and use the || operator.
_.get(room, 'nickname') || _.get(room, 'name')

Since null is falsy, you can do
_.get(room, 'nickname') || 'name'
.get only returns the third argument if the result is undefined
see: https://lodash.com/docs/4.17.10#get

Related

Exception for null fetched data React

I am mapping fetched data like this in React.
I am printing name, column and row to the paragraph so whenever it is null, it prints just null null null, but if warehouse_name is null I need to transfer all values to some String like "Undefined" instead of these tree null.
There can be maybe better solution with using some string method for paragraph instead of this?
const transformedData = data.order_items.map((invoiceData) => {
return {
alternative_warehouse_position: invoiceData.alternative_warehouse_position,
warehouse_column: invoiceData.warehouse_column,
warehouse_name: invoiceData.warehouse_name,
warehouse_row: invoiceData.warehouse_row,
};
3 ways to do it:
Using the "?" to check if its null. Example: ${Condition} ? ${is true} : ${is false}.
Using the new null-checking syntax. Example: ${Value} ?? ${the replacement if its null}
Using the OR operator, which enhances backwards capabilities. Example: ${first condition} || ${Second to replace if the first is false}
Note: Null counts as false
You could use the nullish coalescing operator ??.
const FALLBACK_STRING = "(not set)";
return {
alternative_warehouse_position: invoiceData.alternative_warehouse_position ?? FALLBACK_STRING,
warehouse_column: invoiceData.warehouse_column ?? FALLBACK_STRING,
warehouse_name: invoiceData.warehouse_name ?? FALLBACK_STRING,
warehouse_row: invoiceData.warehouse_row ?? FALLBACK_STRING,
};
If I understand you correctly, you want to replace all three values with one string if invoiceData.warehouse_name is null. You can use the ternary operator (?:) for that.
const transformedData = data.order_items.map(
invoiceData => !!invoiceData.warehouse_name ?
{
alternative_warehouse_position: invoiceData.alternative_warehouse_position,
warehouse_column: invoiceData.warehouse_column,
warehouse_name: invoiceData.warehouse_name,
warehouse_row: invoiceData.warehouse_row
} :
"No data"
);
If what you want to do is to return the "Undefined" string instead of null, then you could try the following code instead:
const transformedData = data.order_items.map((invoiceData) => {
return {
alternative_warehouse_position: invoiceData.alternative_warehouse_position || "Undefined",
warehouse_column: invoiceData.warehouse_column || "Undefined",
warehouse_name: invoiceData.warehouse_name || "Undefined",
warehouse_row: invoiceData.warehouse_row || "Undefined",
}});
If this isn't what you mean, could you elaborate further, especially on the "...but if warehouse_name is null I need to transfer all values to some String like "Undefined" instead of these tree null." part of the problem statement?

Best practice using null in a ternary operator in JavaScript

Hey first time poster/user, I have been working through some coding exercises. I wrote a piece of code that passed tests but I am unsure if this is best practice
In this sample I am iterating over an array using the filter function. I am using a call back function that will return words with length greater than 5.
sample code
const words = ['unique', 'uncanny', 'pique', 'oxymoron', 'guise'];
const interestingWords = words.filter(word => {
return word ? word.length > 5 : null
})
In my head if the condition isn't met it shouldn't even try to return. What is happening when I return a null? or is this a case where I wouldn't use ternary at all.
The best I got was from MDN https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null
The value null is written with a literal: null. null is not an identifier for a property of the global object, like undefined can be. Instead, null expresses a lack of identification, indicating that a variable points to no object. In APIs, null is often retrieved in a place where an object can be expected but no object is relevant.
So should I refrain from returning a null in this context?
All .filter's callback cares about is the truthy or falsey value returned inside it. Here, it'd be better to return that comparison directly, no conditional operator needed:
const interestingWords = words.filter(word => word.length > 5);
A construction like
return word ? word.length > 5 : null
could make sense if you needed to check a sub-property, but only if the array element existed first, eg:
const objects = [
null,
{ word: 'foo' },
{ word: 'barbar' },
null
];
const interestingObjects = objects.filter(
obj => obj ? obj.word.length > 5 : null
);
console.log(interestingObjects);
If elements of the array might be null or undefined, you can use the optional chaining operator.
const interestingWords = words.filter(word => {
return word?.length > 5
})

Destructuring fallback to prevent undefined error?

I have a list of array I do this:
const { id } = myArray.find(
(obj) => obj === true)
If the id is not present it will throw error. How to prevent error in the same time use destructuring? I want to keep the logic in one line.
The issue here is .find() returns undefined once there is no fulfillment for the condition:
The value of the first element in the array that satisfies the provided testing function. Otherwise, undefined is returned.
So probably you can use || operator to check if you have any value returned from .find() or you can replace with empty object {} instead on the right side of the operator.
Probably the option for one-liner is the following:
const myArray = [
{ id: 12 },
{ id: 13 },
{ id: 14 }
];
const { id } = myArray.find(e => e.id === 17) || {};
console.log(id);
So you can destructure id property even if it returned undefined in this way.
Also if you need you can add default value to your destructuring statement based on the documentation which states for Destructuring statement as follows:
A variable can be assigned a default, in the case that the value unpacked from the object is undefined.
const { id = 10 } = {};
console.log(id);
I hope this helps!

Lodash getOr for null

So, I have a prop that will sometimes be null. I want to either get the value or return null.
I am currently doing this:
getOr(
null,
`shift.id`,
ownProps
);
I am getting the shifts.id from the props, however if there's no shift.id I'll get an error back. How can I either return shift.id or null?
The way _.getOr works is that it provides a default value (the first argument) in the case that the value referenced by the path (the second argument) cannot be found in the object (the third argument). It's actually the same as _.get but the argument order is flipped.
An example case is here:
let myObjects = [{
shift: {
id: 1,
example: "text1"
}
},
{
shift: {
id: 2,
example: "text3"
}
},
{
shift: {
example: "text2"
}
}
]
myObjects.forEach((object) => {
let result = _.getOr(null, "shift.id", object)
console.log(result);
})
<script src="https://cdn.jsdelivr.net/g/lodash#4(lodash.min.js+lodash.fp.min.js)"></script>
The console output is:
1
2
null
From what you have described though it's not clear to me that is actually what you are trying to do. Remember, get/getOr will return what's referenced by the path (even if it's already null) unless it's not there (as in undefined), at which point it will return the default value.
So in this case, where there is no shift.id you are asking _.getOr to return null. It sounds like you are then getting an error from GraphQL when you try to use it with a null value. This isn't a problem with lodash in this case, but a problem with your data / how you are using GraphQL.
If this isn't the right tool for the job then I can't suggest anything else without seeing more of your code/knowing more about the problem. I would suggest taking another look at your overall problem and then perhaps asking a different question if needs be.
I have tried your snippet with the sparse information you provided and that works as designed, as far as I understand this.
See also my repl.it.
code
const _ = require('lodash/fp');
var ownProps = { shifts : { id: 'test' }};
console.log(_.getOr(
null,
`shifts.id`,
ownProps
));
ownProps = { shifts : { foo: 'test' }};
console.log(_.getOr(
null,
`shifts.id`,
ownProps
));
output
test
null

How do you implement a guard clause in JavaScript?

I want to guard my functions against null-ish values and only continue if there is "defined" value.
After looking around the solutions suggested to double equal to undefined: if (something == undefined). The problem with this solution is that you can declare an undefined variable.
So my current solution is to check for null if(something == null) which implicetly checks for undefined. And if I want to catch addionalty falsy values I check if(something).
See tests here: http://jsfiddle.net/AV47T/2/
Now am I missing something here?
Matthias
The standard JS guard is:
if (!x) {
// throw error
}
!x will catch any undefined, null, false, 0, or empty string.
If you want to check if a value is valid, then you can do this:
if (Boolean(x)) {
// great success
}
In this piece, the block is executed if x is anything but undefined, null, false, 0, or empty string.
The only safe way that I know of to guard against really undefined variables (meaning having variable name that were never defined anywhere) is check the typeof:
if (typeof _someUndefinedVarName == "undefined") {
alert("undefined");
return;
}
Anything else (including if (!_someUndefinedVarName)) will fail.
Basic example: http://jsfiddle.net/yahavbr/Cg23P/
Remove the first block and you'll get:
_someUndefinedVarName is not defined
Only recently discovered using '&&' as a guard operator in JS. No more If statements!
var data = {
person: {
age: 22,
name: null
}
};
var name = data.person.name && doSomethingWithName(data.person.name);
Ternary to the rescue !
(i) =>
i == 0 ? 1 :
i == 1 ? 2 :
i == 2 ? 3 :
null

Categories

Resources