Separate an object in a array of objects - arrays

Im consuming data from an API
"stats": [
{
"base_stat": 48,
"effort": 1,
"stat": {
"name": "hp",
"url": "https://pokeapi.co/api/v2/stat/1/"
}
},
{
"base_stat": 48,
"effort": 0,
"stat": {
"name": "attack",
"url": "https://pokeapi.co/api/v2/stat/2/"
}
}]
So when i recieve this, im doing =>
const selectedStats = stats.reduce(
(acc, stat) => ({ ...acc, [stat.stat.name]: stat.base_stat }),
{} );
// OUTPUT => stats: {
attack: 48
hp: 48 }
But now im trying to separate an object in a array of objects, like
[{attack: 81}, {hp: 48}, etc]
but i don't know how to do it
Sorry if this is a large question but i don't get the solve. Thanks!

Just mapping the result of Object.entries() would do it:
const stats = {
attack: 48,
hp: 48
};
const data = Object.entries(stats).map(([k, v]) => ({[k]: v}));
console.log(data);
You don't need the intermediate reduce() though. Since you're starting off with an array, you can do everything in a single map() operation:
const stats = [{
"base_stat": 48,
"effort": 1,
"stat": {
"name": "hp",
"url": "https://pokeapi.co/api/v2/stat/1/"
}
}, {
"base_stat": 48,
"effort": 0,
"stat": {
"name": "attack",
"url": "https://pokeapi.co/api/v2/stat/2/"
}
}];
const data = stats.map(({base_stat, stat: {name}}) => ({[name]: base_stat}));
console.log(data);

Related

EDIT-How can I have my specific format using Object.entries?

I have these data from my api (1) and the format I want to have is this one(2), how can I do that in my front-end using Object.entries in REACT, in such a way I can modify my (1) to have (2) please ? I tried but not working...
(1):
{
"myData": [
{
"Peter": 12,
"Donald": 15,
"Huston": 65
}
],
"myOtherData": [
{
"location": "Dublin",
"country":"Irland"
}
]
}
(2):
{
"myData": [
{
"name": "Peter",
"age": "12"
},
{
"name": "Donald",
"age": "15"
},
{
"name": "Huston",
"age": "65"
}
],
"myOtherData": [
{
"location": "Dublin",
"country":"Irland"
}
]
}
I was thinking using destructuration like this :
const d= {myData, myOtherData}
const newData = Object.entries(...)//change myData here ??
Lets be fancy, time to utilise flatMap, array deconstruction and some shortcuts
const a = {
"myData": [{
"Peter": 12,
"Donald": 15,
"Huston": 65
}]
}
console.log({
myData: Object.entries(a.myData[0])
.flatMap(([name, age]) => ({
name,
age
}))
})
const resp = {
"myData": [{
"Peter": 12,
"Donald": 15,
"Huston": 65
}]
}
convertedData = []
for (const person of Object.entries(resp.myData[0])) {
convertedData.push({
name: person[0],
age: person[1]
})
}
const data = {
"myData": [{
"Peter": 12,
"Donald": 15,
"Huston": 65
}]
}
console.log(
Object.entries(data.myData[0])
.reduce( (acc,[name,age])=>acc.concat({name,age}),[] )
)
lets say
var myData = {
"Peter": 12,
"Donald": 15,
"Huston": 65
}
var finalData = Object.entries(myData).map(entry => {
const[key,value] = entry;
return {
name:key,
age:value
}
})
console.log(finalData)

Global state with redux somehow switches variables

I am very confused as to why this is happening as this has never happened with me before using redux. I am building a react native application and currently when I try to console log store.getStore() get the following output.
Object {
"userState": Object {
"currentUser": Object {
"email": "test120#gmail.com",
"username": "test13",
},
"listings": Array [],
},
}
Now, when I dispatch my fetchUserListings() action, which should update the listings in the state the following happens.
Object {
"userState": Object {
"currentUser": Array [
Object {
"addressData": Object {
"description": "2300 Yonge Street, Toronto, ON, Canada",
"matched_substrings": Array [
Object {
"length": 3,
"offset": 0,
},
],
"place_id": "ChIJx4IytjwzK4gRwIPk2mqEJow",
"reference": "ChIJx4IytjwzK4gRwIPk2mqEJow",
"structured_formatting": Object {
"main_text": "2300 Yonge Street",
"main_text_matched_substrings": Array [
Object {
"length": 3,
"offset": 0,
},
],
"secondary_text": "Toronto, ON, Canada",
},
"terms": Array [
Object {
"offset": 0,
"value": "2300",
},
Object {
"offset": 5,
"value": "Yonge Street",
},
Object {
"offset": 19,
"value": "Toronto",
},
Object {
"offset": 28,
"value": "ON",
},
Object {
"offset": 32,
"value": "Canada",
},
],
"types": Array [
"street_address",
"geocode",
],
},
"addressDescription": "2300 Yonge Street, Toronto, ON, Canada",
"bath": "6",
"benefits": Array [
"Large Beds",
"Nearby Bustop",
"In-building gym",
],
"urls": Array [
"https://firebasestorage.googleapis.com/v0/b/studenthousingfinder-11f55.appspot.com/o/listing%2FoHr0OMukEFguYxJborrvMAJQmre2%2F0.bd7cwka5gj?alt=media&token=81b3e06a-65a9-44a7-a32d-d328014058e7",
"https://firebasestorage.googleapis.com/v0/b/studenthousingfinder-11f55.appspot.com/o/listing%2FoHr0OMukEFguYxJborrvMAJQmre2%2F0.k78etqzypk?alt=media&token=e2622547-00f4-447b-8bea-799758734f0d",
],
},
],
"listings": Array [],
},
}
Basically the API call is working and the state is updated, however somehow the data sent back is updating the currentUser in the state rather than the listings.
Here is my current reducer code:
import {USER_LISTINGS_STATE_CHANGE, USER_STATE_CHANGE} from '../constants';
const initialState = {
currentUser: null,
listings: [],
};
export const userReducer = (state = state || initialState, action) => {
switch (action.type) {
case USER_STATE_CHANGE:
return {
listings: state.listings,
currentUser: action.payload,
};
case USER_LISTINGS_STATE_CHANGE:
return {
currentUser: state.currentUser,
listings: action.payload,
};
default:
return state;
}
};
and here are the 2 functions I use to make the API request
export function fetchUser() {
return async (dispatch) => {
db.collection('users')
.doc(auth.currentUser.uid)
.get()
.then((snapshot) => {
if (snapshot.exists) {
console.log('Yo');
dispatch({type: USER_STATE_CHANGE, payload: snapshot.data()});
} else {
console.log('Does not exist');
}
});
};
}
export function fetchUserListings() {
return async (dispatch) => {
db.collection('posts')
.doc(auth.currentUser.uid)
.collection('userListings')
.orderBy('title', 'desc')
.get()
.then((snapshot) => {
let listingArr = snapshot.docs.map((doc) => {
const data = doc.data();
const id = doc.id;
return {id, ...data};
});
dispatch({
type: USER_LISTINGS_STATE_CHANGE,
payload: listingArr,
});
});
};
}
Any help would be appreciated as I'm really lost as to why this is happening!
It seems like that your users collection in database might be having wrong entry.
Fact that brought me to this conclusion is that in your fetchUserListings() function, you're actually adding an extra field to json object i.e id.
Now, the console.log output doesn't contain this id field which could only mean that fetchUserListings() is not the one being called here.
You can try putting some try catch block and console.log('fetchUser', snapshot.data()) & console.log('fetchUserListings', snapshot.docs) in respective functions to see which one is being called.

TypeError: Cannot read property 'temp' of undefined

I am trying to access data from OpenWeather API and it has nested objects and I keep getting the error trying to access data in these nested objects. I can access values from the parent object but no from nested ones.
this is me passing data to the component.
const Card = ({ cardRef }) => {
const [data, setData] = useState({});
useEffect(() => {
setData({ ...cardRef });
console.log(data.main.temp);
}, [cardRef]);
I can access data.main but not data.main.temp
below in the data being passed
{
"coord": {
"lon": -0.2,
"lat": 5.56
},
"weather": [
{
"id": 500,
"main": "Rain",
"description": "light rain",
"icon": "10d"
}
],
"base": "stations",
"main": {
"temp": 304.15,
"feels_like": 304.86,
"temp_min": 304.15,
"temp_max": 304.15,
"pressure": 1011,
"humidity": 66
},
"visibility": 10000,
"wind": {
"speed": 7.2,
"deg": 190
},
"rain": {
"1h": 0.29
},
"clouds": {
"all": 20
},
"dt": 1607092023,
"sys": {
"type": 1,
"id": 1126,
"country": "GH",
"sunrise": 1607061413,
"sunset": 1607103947
},
"timezone": 0,
"id": 2306104,
"name": "Accra",
"cod": 200
}
Since setData is the asynchronous method, you can't get the updated value of data immediatley after setData.
const Card = ({ cardRef }) => {
const [data, setData] = useState({});
useEffect(() => {
setData({ ...cardRef });
console.log(data.main.temp); // data is still the old value which is initial empty {} value, so `data.main` is undefined and `data.main.temp` will be error.
}, [cardRef]);
You should get it inside useEffect with adding a data dependency.
useEffect(() => {
if (data.main) { // Make sure that you need to check if `data.main` is not undefined before referring `data.main.temp`.
console.log(data.main.temp);
}
}, [data]);

I need to find least count by iterating child array and seperate as multiple arrays based on parent array in angular

myData = [
{
id: 'N5604-E',
areas: [
{
test_per_week: 154,
test_per_day: 22,
},
{
test_per_week: 154,
test_per_day: 52,
},
{
test_per_week: 154,
test_per_day: 32,
},
],
},
{
id: 'RSP4-E',
areas: [
{
test_per_week: 154,
test_per_day: 12,
},
{
test_per_week: 154,
test_per_day: 29,
},
],
},
];
I need to get minimum test_per_week in each area and need to store values in an array based on IDs
I have tried iterating using for loop and for each loop:
for (let i = 0; i < this.data.length; i++) {
this.chartProducts.push(this.data[i].id);
this.capacity[i].areas.forEach((element) => {
this.myData.push(element.test_per_day);
});
}
I stuck on how to calculate the min count of test_per_day for all areas in one ID.
This can be done using Array.map() combined with Math.min() as follows:
const result = myData.map(o => ({
id: o.id,
min_per_day: Math.min(...o.areas.map(a => a.test_per_day))
}));
Please have a look at the runnable code snippet below.
const myData = [{
"id": "N5604-E",
"areas": [
{ "test_per_week": 154, "test_per_day": 22 },
{ "test_per_week": 154, "test_per_day": 52 },
{ "test_per_week": 154, "test_per_day": 32 }
]
},
{
"id": "RSP4-E",
"areas": [
{ "test_per_week": 154, "test_per_day": 12 },
{ "test_per_week": 154, "test_per_day": 29 }
]
}
];
const result = myData.map(o => ({
id: o.id,
min_per_day: Math.min(...o.areas.map(a => a.test_per_day))
}));
console.log(result);
We used a map method for iterating and return a new array and reduce for comparing the values between together and finally using the min mathematical method to get the minimum number.
const result = myData.map((item) => {
const test_per_day = item.areas.reduce(
(max, val) => Math.min(max, val.test_per_day),
item.areas[0].test_per_day
);
return { id: item.id, test_per_day };
});
Result:
[
{
"id": "N5604-E",
"test_per_day": 22
},
{
"id": "RSP4-E",
"test_per_day": 12
}
]

Reduce array of json to json object

I have details as
data = {
name: "charles",
id: "1",
education: [
{"class": "X","marks": 223,"percentage": "59%"},
{"class": "IX","marks": 223,"percentage": "59%"},
{"class": "IIX","marks": 223,"percentage": "59%"},
{"class": "IIIX","marks": 223,"percentage": "59%"}
]
}
My desired result need is to break into 4 json objects
{name:"charles",id:"1", education:{"class":"X","marks":223,"percentage":59%}}
{name:"charles",id:"1", education:{"class":"IX","marks":223,"percentage":59%}}
Can anyone let me know how to achieve it?
I am sucessfully by looping and creating each object induvidually as follows:
this.data.education.forEach( class => {
const newData: any = {};
newData.name= data.name;
newData.id= data.id;
newData.education = class ;
array.push(newData);
});
I am looking for any simplist way of achieving it?
You need to extract name and id and pass along all entries of education array. Hope this helps
const data = { name: "charles", id: "1", education: [
{ "class": "X", "marks": 223, "percentage": 59 },
{ "class": "IX", "marks": 223, "percentage": 59 },
{ "class": "IIX", "marks": 223, "percentage": 59 },
{ "class": "IIIX", "marks": 223, "percentage": 59 }
]
};
const {name, id} = data;
const response = data.education
.reduce((result, education) => ([...result, {name, id, education}]), []);
console.log(response)
const newData = data.education
.map(e => ({ id: data.id, name: data.name, education: e}))

Resources