Reputation: 3273
Many times I ask myself the same question... With all that syntaxes (not always intuitive) to write quite direct code in JS, I was wondering, would someone know about a one-liner for that kind of operation?
var setFeatured = entry => {
entry.isFeatured = true;
return entry
}
SomeCallThatReturnsAPromise.then(entries => entries.map(setFeatured))
To assign a property and return the object in one shot, that I could put in a readable way directly as arg of entries.map
To give a feedback about what was proposed to me, the common answer was to return a result with a OR operator, after an assignation or function call (which returns undefined
, null
, false
, never
, well anything that will trigger the part after the OR):
return entry.isFeatured = true || entry
The interest of my question was to know if I could take advantage of a more compact syntax:
SomeCallThatReturnsAPromise()
.then((entries:EntryType[]) => entries
.map(entry => entry.isFeatured = true || entry)
.filter(entry => entry.something == true))
.then((entries:EntryType[]) => someCallThatReturnsNothingButHasToBeDoneThere() || entries)
.then((entries:EntryType[]) => console.log(entries))
would be easier to read than:
SomeCallThatReturnsAPromise
.then((entries:EntryType[]) => entries
.map(entry => {
entry.isFeatured = true;
return entry;
})
.filter(entry => entry.something == true))
.then((entries:EntryType[]) => {
someCallThatReturnsNothingButHasToBeDoneThere();
return entries;
})
.then((entries:EntryType[]) => console.log(entries))
Notes:
1) I try to avoid creating a function for that. My question was motivated by curiosity and just concerns what Vanilla ES6 or 7 syntaxes have to offer.
2) I was answered to use .forEach
rather than .map
. I design my code with a functional approach (hence the importance of compact callbacks), so .forEach
is not necessarily a good choice for me (and apparently it doesn't have advantages over map in terms of performance or memory consumption). A one-line syntax is convenient both when handling promises callbacks or chains of array functions...
3) the returned type when using the OR operator is a union type, EntryType|null
. So it breaks the typing for the subsequent calls and implies a type assertion:
SomeCallThatReturnsAPromise()
.then((entries:EntryType[]) => entries
.map(entry => (entry.isFeatured = true || entry) as EntryType)
.filter(entry => entry.something == true))
.then((entries:EntryType[]) => (someCallThatReturnsNothingButHasToBeDoneThere() || entries) as EntryType[])
.then((entries:EntryType[]) => console.log(entries))
That's getting heavier... I still don't know if I'll use that or stick with the two lines including the return statement.
4) That's a reduced example. I know that my first then
contains a synchronous call or that my example could be more accurate.
Upvotes: 0
Views: 10039
Reputation: 36
//Example 1
const gimmeSmile = {}
console.log({ ...gimmeSmile, smile: ":)" })
// Example 2
const smiles = [{},{},{}]
.map(obj => ( { ...obj, smile: ":)"} ));
console.log(smiles)
Upvotes: 1
Reputation: 164457
You can do what @Sirko wrote but return it like so:
SomeCallThatReturnsAPromise.then(entries => entries.forEach(entry => entry.isFeatured = true) || entries)
There's no need to use map
, instead using forEach
will give you a "one-liner", but then you want to return the same value that you received, using logical or (||
) you can do that.
Upvotes: 4
Reputation: 2555
although @Sirko is right and, in that specific case, forEach
has more sense than using map
I think the OP was asking a generic question.
So, in general, how do you assign a property and then return the whole object? this is my suggestion:
function mutateObject(element, value) {
return (element.prop = value) && element || element
}
var object = {prop:1}
var returned = mutateObject(object, 2)
console.log(returned)
How does it work? the first part (element.prop = value)
assigns the value
to the property and return the value
to the expression.
If the value returned is falsy, the value of the ||
clause is returned. If it's truthy the value of the &&
is returned.
In this case we return the element
itself both times to be sure that's the object it will always be returned, no matter what we set in the property.
Another way to write that is (element.prop = value) ? element : element
but, with this syntax, it looks more like a typo with the assignment instead of the comparison so I like the other syntax better.
Upvotes: 2
Reputation: 74106
entries.forEach( (entry) => entry.isFeatured = true );
No need to define the function separately.
Furthermore, as your elements are objects and are handled by reference, one can replace map()
by forEach()
, which removes the necessity to return a value.
(using map()
you would end up with two arrays consisting of the same elements, which probably is not, what you need)
Upvotes: 7