Javascript (es6) possible to destructure and return on a single line? - ecmascript-6

I'm curious if it's possible to return a destructured object on the same line it was destructured.
Current (working) examples:
using 2 lines
const itemList = json.map((item) => {
const { id, title } = item;
return { id, title };
});
1 line but not destructured
const itemList = json.map((item) => {
return { id: item.id, title: item.title }; // This also requires repeating the field name twice per instance which feels hacky
});
Is it possible to condense the body down to one line ?
example (doesn't work)
const itemList = json.map((item) => {
return { id, title } = item;
}

Destructure the callback parameters, and return an object:
const itemList = json.map(({ id, title }) => ({ id, title }))

Related

React Beautiful DnD, multiple columns inside single droppable

I am trying to have a grid column layout, (2 columns) inside a single droppable container. The project is for an online menu where you can create a menu item, which goes into a droppable container, then you can drag that onto the menu that will be displayed to the user. So there is currently two columns. However the style of the menu demands two columns. Currently I am assigning different classNames to the mapped columns so I can make one of them grid but its pretty messy. Maybe there is a way I can hardcode the droppable instead of map them and run the map on the lists themselves inside each of the hardcoded droppables? Sorry if this is confusing, it sure is for me.
'results' is API data that is initially mapped into savedItems array where newly created menu items will go. Later on menuItems array will pull from the database as well. Right now just trying to have better styling control over the different droppables.
you can see where im assigning different classNames to the droppable during the mapping and its really not a reliable option.
//drag and drop states
const [state, setState] = useState({
menuItems: {
title: "menuItems",
items: []
},
savedItems: {
title: "savedItems",
items: results
}
})
useEffect(() => {
setState({ ...state, savedItems: { ...state.savedItems, items: results } })
}, [results])
// console.log("state", state)
console.log("dummy data", dummyArry)
// updating title graphql mutation
const [elementId, setElementId] = useState(" ");
const updateTitle = async () => {
//api data
const data = await fetch(`http://localhost:8081/graphql`, {
method: 'POST',
body: JSON.stringify({
query: `
mutation {
updateMenu(menuInput: {_id: ${JSON.stringify(elementId)},title: ${JSON.stringify(inputValue)}}){
title
}
}
`
}),
headers: {
'Content-Type': 'application/json'
}
})
//convert api data to json
const json = await data.json();
}
//drag end function
const handleDragEnd = (data) => {
console.log("from", data.source)
console.log("to", data.destination)
if (!data.destination) {
// console.log("not dropped in droppable")
return
}
if (data.destination.index === data.source.index && data.destination.droppableId === data.source.droppableId) {
// console.log("dropped in same place")
return
}
//create copy of item before removing from state
const itemCopy = { ...state[data.source.droppableId].items[data.source.index] }
setState(prev => {
prev = { ...prev }
//remove from previous items array
prev[data.source.droppableId].items.splice(data.source.index, 1)
//adding new item to array
prev[data.destination.droppableId].items.splice(data.destination.index, 0, itemCopy)
return prev
})
}
const columnClass = [
"menuItems-column",
"savedItems-column"
]
let num = 0
return (
<>
<div className='app'>
{results && <DragDropContext onDragEnd={handleDragEnd}>
{_.map(state, (data, key) => {
return (
<div key={key} className='column'>
<h3>{data.title}</h3>
<Droppable droppableId={key}>
{(provided, snapshot) => {
return (
<div
ref={provided.innerRef}
{...provided.droppableProps}
className={columnClass[num]}
// className="droppable-col"
><span className='class-switch'>{num++}</span>
{data.items.map((el, index) => {
return (
<Draggable key={el._id} index={index} draggableId={el._id}>
{(provided) => {
return (
<div className='element-container'
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
>
<div contentEditable="true">
{el.title}
</div>
</div>
)
}}
</Draggable>
)
})}
{provided.placeholder}
</div>
)
}}
</Droppable>
</div>
)
})}
</DragDropContext>}
</div>
</>
)
}

*ngIf display then undisplay

I write this after asking that: Observable need a click to load on html page
The solution was good but the problem now is that I have every same id display because precedently I did :
getFeederArray(): Observable<Array<string>> {
let toReturn: Array<string> = [];
var subject = new Subject<Array<string>>();
this.getUser().subscribe(user => {
this.orders = this.db.collection("orders", ref => {
return ref
.where("clientId", "==", user.id)
}).valueChanges({ idField: 'id' }) as Observable<Order[]>;
this.orders.subscribe(orders => {
orders.forEach(order => {
if(toReturn.indexOf(order.feederId) == -1) { <---- to not have twice the same order
toReturn.push(order.feederId);
}
})
})
subject.next(toReturn);
})
return subject.asObservable();
}
And now I have :
getFeederArray(): Observable<string[]> {
return this.getUser().pipe(
switchMap((user) => {
this.orders = this.db
.collection("orders", (ref) => ref.where("clientId", "==", user.id))
.valueChanges({ idField: "id" }) as Observable<Order[]>;
return this.orders;
}),
map((orders) => orders.map((order) => order.feederId))
);
}
Which no need a click no more, so the display is normal, but we can have twice the same order.
So I tried in my html :
<section class="mobile" fxLayout="column" fxLayoutAlign="center center" fxLayoutGap="20px" *ngFor="let id of _feedersId | async">
<div *ngIf="this.isAlreadyDisplayed(id)">
{{ cl(id) }}
<app-feeder-card
[feederId] = "id"
[clientId] = "this.uid"
></app-feeder-card>
</div>
</section>
With those functions in the .ts:
// push in array
pushAlreadyDisplayed(str: string) {
this.alreadyDisplayed.push(str);
}
// boolean already displayed
isAlreadyDisplayed(str: string): boolean {
const bool = this.alreadyDisplayed.includes(str);
if(bool) {
return !bool;
} else {
this.pushAlreadyDisplayed(str);
return !bool;
}
}
cl(str: string) {
console.log(str);
}
But a problem occurs : my page well console.log the ids (and that's good, there is no twice the same), but this part in the HTML :
{{ cl(id) }}
<app-feeder-card
[feederId] = "id"
[clientId] = "this.uid"
></app-feeder-card>
is only showed for less than 1 second and than disapear...
I don't understand why, and so I don't know how to solve my problem...
Thank you for your time
Well, when you use pushAlreadyDisplayed() you make changes to alreadyDisplayed.
This thing cus to re-render the component, and on the 2nd iteration the ID is
marked as arealy renderd aleady.
A better solution is to reduce the array from the duplicates

ipfs.add() returns Object [AsyncGenerator] {}

I am unable to figure out what mistake i have done in the code
Whenever i am calling api, ipfs.add('hello') returns [object AsyncGenerator]
https://gateway.ipfs.io/ipfs/[object AsyncGenerator]
const addFile = async () => {
const Added = await ipfs.add('hello');
return Added;
}
const fileHash = await addFile();
return fileHash;
You can iterate over the result of .add() like so:
for await (const item of Added) {
console.log('item', item)
}
item { path: 'QmWfVY9y3xjsixTgbd9AorQxH7VtMpzfx2HaWtsoUYecaX',
cid: CID(QmWfVY9y3xjsixTgbd9AorQxH7VtMpzfx2HaWtsoUYecaX), size: 13 }

Derive HTML based on value of nested array

Looking to group and create relevant html based from an object.
const _ = require('lodash');
const items = [
{
value: 'fruit',
label: 'apple',
},
{
value: 'Mango',
label: 'Mango',
groupBy: 'fruit'
},
{
value: 'Orange',
label: 'Orange',
groupBy: 'fruit'
},
// Will need to group all above by fruit, similarly
{
value: 'vegetable',
label: 'artichoke',
},
{
value: 'aubergine',
label: 'aubergine',
groupBy: 'vegetable'
}
];
_renderItems = () => {
const itemsList = _.chain(items)
.map(item => (
this._renderItem(item)
))
.value()
return '<div class="item-container">'+ itemsList+'</div>'
}
_renderItem = (item = {}) => {
console.log(item)
}
_renderItems()
/*
desired output
<div class="fruit">
Label:Apple
Label:Mango
Label:Orange
</div>
<div class="vegetable">
label:artichoke
label:aubergine
label:broccoli
</div>
*/
Code sample here of progress here https://repl.it/repls/ElectronicUsableTheories . In general, I have trouble adding a wrapping div based on grouped value.
So all fruit should be grouped first key will not have groupBy key but its value will be the key of all next items which needs to be grouped
Group the items by the groupBy or by value if groupBy doesn't exist. Then you can map the groups. The 2nd parameter that map passes to the callback is the key (the groupBy value), that you can use as the class. It addition map the items, take the label, and format. Combine the group's string, and the itemList's string, and return.
const items = [{"value":"fruit","label":"apple"},{"value":"Mango","label":"Mango","groupBy":"fruit"},{"value":"Orange","label":"Orange","groupBy":"fruit"},{"value":"vegetable","label":"artichoke"},{"value":"aubergine","label":"aubergine","groupBy":"vegetable"}];
const _renderItem = ({ label } = {}) => `label: ${label}\n`;
const _renderItems = () =>
_(items)
.groupBy(o => o.groupBy || o.value) // if not groupBy use value
.map((group, key) => {
const itemsList = group.map(_renderItem).join('');
return `<div class="item-container ${key}">\n${itemsList}</div>`;
})
.join('\n');
const result = _renderItems();
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

React--Div exists, but is empty & more problems

I'm using the code below to pull in a list of data from a JSON file in order to populate a webpage with News. However, with what I have, the div is empty when I inspect it, and I'm not sure why. When I attempt other solutions, I get errors or the same output.
const newsList = labNewsJson['news']
class News extends Component {
render() {
const news = newsList.map((newsItem) => {
<div>{newsItem}</div>
});
return (
<div className='container'>
<h1>Lab News</h1>
<div>{news}</div>
</div>
);
}
}
export default News;
You need to add a return to your map function.
const news = newsList.map((newsItem, index) => {
return <div key={index}>{newsItem.title}</div>
});
When you are using {}, map function does not return anything. You have two options:
1- Try to use () instead of {}:
const news = newsList.map((newsItem) => (
<div>{newsItem}</div>
))
2- Return the item in every iteration:
const news = newsList.map((newsItem) => {
return <div>{newsItem}</div>
})