How to Manage the response of the API in react? - arrays

i did a request to the API, then the response is as the following:
data1 = [{id: 1, code:1, title:title1}, {id:2, code:3, title:title2}, ...]
Now i would like to extract an array of the titles of the above response as below:
titles = [title1, title2, ....]
how can i do it by map?
And the second question:
Consider if the response would be as follow:
data2 = [{id: 1, code:1, title:title1, chapters:[{id:1, chapter: chapter1},{id:2, chapter: chapter2}, ...]}, {id:4, code:5, title:title3, chapters:[{id:4, chapter: chapter3}, ...]}, ...]
In this case how can i extract an array of the chapters as following:
chapters = [chapter1, chapter2, chapter3]
I tried to do them as below:
for the first question:
title = data1.map((item) => {item.title})
for the second one i did:
chapters = data2.chapters.map((item) => {item.chapter})
But it doesn't work. I think some where there are error in syntaxes.
Can any one help me how to manage these data?
Thank you.

Yep, you are wrong with syntax.
Firs case - title = data1.map((item) => {item.title})
You've wrapped item.title with {}, so you should add return. Or omit {}.
For example: title = data1.map(item => item.title)
Second case - same issue with {}, but you should also use flatMap because you need flat list in result. If you write with regular map - you won't get desired ["chapter1", "chapter2"].
See also detailed example below.
const data1 = [
{ id: 1, code: 1, title: "title1" },
{ id: 2, code: 3, title: "title2" }
];
const data1_mapped = data1.map(d => d.title);
console.log(data1_mapped);
const data2 = [
{
id: 1,
code: 1,
title: "title1",
chapters: [{ id: 1, chapter: "chapter1" }, { id: 2, chapter: "chapter2" }]
},
{
id: 2,
code: 2,
title: "title2",
chapters: [{ id: 1, chapter: "chapter22" }, { id: 2, chapter: "chapter32" }]
}
];
const data2_mapped = data2.flatMap(d => d.chapters.map(c => c.chapter));
console.log(data2_mapped);

You are not returning a value. Try removing braces like so...
title = data1.map((item) => item.title)
chapters = data2.chapters.map((item) => item.chapter)
See this for more info on the issue:
Meaning of curly braces in array.map()

Related

update an object with useState hook in React

I have an object in board variable
Initial Data:
const [board, setBoard] = useState({
lanes: [],
});
{
lanes: [{
title: 'Bugs',
id: 'd83706b0-b252-11ec-8845-ad6b1e4ecd03',
cards: [{
id: null,
title: 'Bug #1',
description: 'Can AI make memes',
}, ],
},
{
title: 'Tests',
id: 'd83706b0-b252-11ec-8845-ad6b1e4ecd04',
cards: [{
id: null,
title: 'Test #1',
description: 'Can AI make memes',
}, ],
},
],
};
I want to add a new element to the cards array but only to the first element in the lanes array. Other answers seem to point to having to use a callback pattern, but I am quite unfamiliar with this.
Thanks for any help.
As for any modification you want to do on a useState variable, you must use an arrow function inside of the "set" function.
You can do something like that :
setBoard((currentBoard)=> {
currentBoard.lanes[0].cards = [...currentBoard.lanes[0].cards, whateverCardYouWantToAdd ]
return {... currentBoard} //necessary to create a new object because else the hook won't be updated
})
Maybe with this.
const addValue = () => {
let t = [...board];
t[0].lanes.cards.push({
id: null,
title: "Bug #1",
description: "Can AI make memes"
});
};

Map Angular Array to Object

I have been looking and have found a few good references for transforming arrays to objects, but I can't seem to find my use case. I have an array with the following format
[
{id: 1, name: 'hello', display: false},
{id: 5, name: 'hello2', display: true},
{id: 7, name: 'hello8', display: true},
]
and I would like to map it into something like this
{
5: {id: 5, name: 'hello2'},
7: {id: 7, name: 'hello8'}
}
I have been trying to use the map function, but I can't figure it out since I want the keys of my map to be an id. This is what I have so far but it is obviously wrong.
const myArray = [
{id: 1, name: 'hello', display: false},
{id: 5, name: 'hello2', display: true},
{id: 7, name: 'hello8', display: true},
];
const myMap = myArray.filter(row => row.display)
.map(row => {
return {row.id: {id: row.id, name: row.name}
});
Filter the array, map it to pairs of [id, obj], and convert to an object using Object.fromEntries(). You can use destructuring and rest syntax (...) to remove display.
Notes: if Object.fromEntries() is not supported, change target in TS Config to ES2019.
const arr = [{id: 1, name: 'hello', display: false},{id: 5, name: 'hello2', display: true}, {id: 7, name: 'hello8', display: true}]
const result = Object.fromEntries(
arr.filter(o => o.display)
.map(({ display, ...o }) => [o.id, o])
)
console.log(result)
Another option is to use Array.reduce() to create the object. In that case, you can skip objects with false display.
const arr = [{id: 1, name: 'hello', display: false},{id: 5, name: 'hello2', display: true}, {id: 7, name: 'hello8', display: true}]
const result = arr.reduce((acc, { display, ...o }) => {
if(display) acc[o.id] = [o.id, o]
return acc
}, {})
console.log(result)

Filter out items in an array where a specified element is a null string

I'm very new to JS, and what I'm trying to do is create a new array that filters out elements in an existing array that have a null value. In my example code below, I would want to create a new array that filters out the third item because the url is an empty string (I only want it to filter based on whether the url is an empty string). I should add that the const is being exported as part of a reducer, and in the file it's actually used in, we're calling on {props.categories}. Any help is greatly appreciated!!!
const categories = () => {
return [
{
id: 0,
title: "Google",
url: "www.google.com",
},
{
id: 1,
title: "Firefox",
url: "www.firefox.com",
},
{
id: 2,
title: "Placeholder",
url: "",
},
];
};
Arrays have a filter function that takes a function to return true/false if the current element should be filtered through to the result array.
const categories = [
{
id: 0,
title: "Google",
url: "www.google.com",
},
{
id: 1,
title: "Firefox",
url: "www.firefox.com",
},
{
id: 2,
title: "Placeholder",
url: "",
},
];
const filterBlankUrl = arr => arr.filter(({ url }) => !!url);
const filteredCats = filterBlankUrl(categories);
console.log(filteredCats);
Thanks so much everyone for your help! I did actually finally figure it out; in the file where I was actually referencing the array, I needed to update the code to this:
options={props.categories.filter(categories => categories.url !== "")}

What is an example of normalizing the state in a React Redux app?

I'm reading the Redux Reducers docs and don't get how normalizing the state would work. The current state in the example is this:
{
visibilityFilter: 'SHOW_ALL',
todos: [
{
text: 'Consider using Redux',
completed: true,
},
{
text: 'Keep all state in a single tree',
completed: false
}
]
}
Can you provide an example of what the above would look like if we followed the below?
For
example, keeping todosById: { id -> todo } and todos: array inside
the state would be a better idea in a real app, but we’re keeping the
example simple.
This example is straight from Normalizr.
[{
id: 1,
title: 'Some Article',
author: {
id: 1,
name: 'Dan'
}
}, {
id: 2,
title: 'Other Article',
author: {
id: 1,
name: 'Dan'
}
}]
Can be normalized this way-
{
result: [1, 2],
entities: {
articles: {
1: {
id: 1,
title: 'Some Article',
author: 1
},
2: {
id: 2,
title: 'Other Article',
author: 1
}
},
users: {
1: {
id: 1,
name: 'Dan'
}
}
}
}
What's the advantage of normalization?
You get to extract the exact part of your state tree that you want.
For instance- You have an array of objects containing information about the articles. If you want to select a particular object from that array, you'll have to iterate through entire array. Worst case is that the desired object is not present in the array. To overcome this, we normalize the data.
To normalize the data, store the unique identifiers of each object in a separate array. Let's call that array as results.
result: [1, 2, 3 ..]
And transform the array of objects into an object with keys as the id(See the second snippet). Call that object as entities.
Ultimately, to access the object with id 1, simply do this- entities.articles["1"].
You can use normalizr for this.
Normalizr takes JSON and a schema and replaces nested entities with their IDs, gathering all entities in dictionaries.
For example,
[{
id: 1,
title: 'Some Article',
author: {
id: 1,
name: 'Dan'
}
}, {
id: 2,
title: 'Other Article',
author: {
id: 1,
name: 'Dan'
}
}]
can be normalized to
{
result: [1, 2],
entities: {
articles: {
1: {
id: 1,
title: 'Some Article',
author: 1
},
2: {
id: 2,
title: 'Other Article',
author: 1
}
},
users: {
1: {
id: 1,
name: 'Dan'
}
}
}
}

Ext.data.TreeStore modified the data source after the tree is rendered?

Let's say I have the data source as following:
var data = [
{
id: 1,
name: 'name1',
parentId: null,
children: [
{
id: 2,
name: 'name2',
parentId: 1
}
]
},
{
id: 3,
name: 'name3',
parentId: null,
children: [
{
id: 4,
name: 'name4',
parentId: 3
}
]
}
]
And the code snippets like following:
var basic_grid_store = Ext.create('Ext.data.TreeStore', {
storeId: 'basic_grid_store',
model: 'TestModel',
root: {
children: []
}
});
console.log(data);
// the data structure is correct at this time
basic_grid_store.setRootNode({children: data);
console.log(data);
// the data structure is incorrect at this time, in which the `children` attribute for each item was gone.
I could not find any documentation for this, can someone tell why TreeStore modified my data source since it should not happen?
Yeah, it does change the original array. I cannot answer why this behavior, you would need to ask Ext architects/developers, but what you can try is:
basic_grid_store.setRootNode({children:Ext.clone(data)});

Resources