How to extract specific key/value during Http call in angular? - arrays

Through a HTTP call I am having a JSON file like bellow:
[
{
"totalConfirmed": 555,
"mainlandChina": 548,
"otherLocations": 7,
"deltaConfirmed": 555,
"totalRecovered": 0,
"confirmed": {
"total": 555,
"china": 548,
"outsideChina": 7
},
"deaths": {
"total": 17,
"china": 17,
"outsideChina": 0
},
"reportDate": "2020-01-22"
},
{
"totalConfirmed": 654,
"mainlandChina": 643,
"otherLocations": 11,
"deltaConfirmed": 99,
"totalRecovered": 0,
"confirmed": {
"total": 654,
"china": 643,
"outsideChina": 11
},
"deaths": {
"total": 18,
"china": 18,
"outsideChina": 0
},
"reportDate": "2020-01-23"
}
]
from that, I want to store the value of totalConfirmed, deaths & reportDate.
So my return would be something like this
{
totalConfirmed : [555,654],
death: [17, 18],
dates: ["2020-01-22", "2020-01-23"]
}
Here is the function that I have written in my service.ts:
public filteredData(): Observable<History> {
let dataHistory: History;
return this.httpClient.get(this.hostURL).pipe(
map(res => {
dataHistory.totalConfirmedPerDay.push(res["totalConfirmed"]);
dataHistory.totalDeathPerDay.push(res["deaths"]["total"]);
dataHistory.dates.push(res["reportDate"]);
return dataHistory;
})
);
}
and here is my History interface:
export interface History {
totalConfirmedPerDay: any[];
totalDeathPerDay: any[];
dates: any[any];
}
But unfortunately, it's now working. I am having this error:
ERROR TypeError: Cannot read property 'totalConfirmedPerDay' of undefined

You may do so using:
return this.httpClient.get(this.hostURL)
.pipe(
map(arr => {
return arr.map(sub => {
return {
totalConfirmed: sub.totalConfirmed,
totalDeathPerDay: sub.deaths.total,
dates: sub.reportDate
};
});
})
)
now in the subscription block:
.subscribe(res => {
let op: History = {
totalConfirmedPerDay: [],
totalDeathPerDay: [],
dates: []
};
res.forEach(e => {
op.totalConfirmedPerDay.push(e.totalConfirmedPerDay);
op.totalDeathPerDay.push(e.totalDeathPerDay);
op.dates.push(e.dates);
});
});

Typo mistake: dataHistory is not initialized.
public filteredData(): Observable<History> {
return this.httpClient.get(this.hostURL).pipe(
map(res => {
return {
totalConfirmedPerDay: res.totalConfirmed,
totalDeathPerDay: res.deaths.total,
dates: res.reportDate
};
})
);

The way to do map is
map((full:any[]) => { //I don't want full
full.map(res=>{ //I want a "resumed" of full
const obj={ //transform each element of full
totalConfirmed:res.totalConfirmed,
totalDeathPerDay:res.deaths.total,
dates.res.reportDate
}
return obj;
)
return full;
})

Related

ERROR TypeError: tags.tagName.indexOf is not a function: Angular: Filter Observable<SomeObject[ ]> provided with a substring as a parameter

The situation:
I have a class with two properties, id and tagName. I have a json file with an array that matches said class. I want to extract all the items in the array that their tagName contains a given substring as a parameter, not equal to tagName but anywhere within the string. I am trying this in a service, in a function that returns an observable of type said class above. In the following attempts below I will be using "java" as the search parameter.
The class:
export class TechTag {
id?: number;
tagName!: string;
}
The function inside de service that returns every object:
getAllTechTags(): Observable<TechTag[]> {
return this.http.get<TechTag[]>(this.baseUrl);
}
Url of JSON file:
"../assets/techTags.json"
Sample of the file:
[
{
"id": 1,
"tagName": ".net"
},
{
"id": 2,
"tagName": "html"
},
{
"id": 3,
"tagName": "javascript"
},
{
"id": 4,
"tagName": "css"
},
{
"id": 5,
"tagName": "php"
},
{
"id": 8,
"tagName": "c"
},
{
"id": 9,
"tagName": "c#"
},
{
"id": 10,
"tagName": "c++"
},
How I check the results in the component:
ngOnInit(): void {
let techTags: TechTag[];
this.techTagsService.searchTechTags("java").subscribe(
{
next: (response => {
techTags = response;
}),
complete: () => {
console.log(techTags);
}
}
);
}
My attempts:
Attempt #1
searchTechTags(tagName: string): Observable<TechTag[]> {
return this.http.get<TechTag[]>(this.baseUrl).pipe(map(data => data.filter(tags =>
tags.tagName == tagName)));
}
Result #1 (only returns java)
[
{
"id": 17,
"tagName": "java"
}
]
Attempt #2
searchTechTags(tagName: string): Observable<TechTag[]> {
return this.http.get<TechTag[]>(this.baseUrl).pipe(map(data => data.filter(tags =>
tagName.includes(tags.tagName))));
}
Result #2 (doesn't return javascript)
[
{
"id": 17,
"tagName": "java"
},
{
"id": 11644,
"tagName": "j"
},
{
"id": 118435,
"tagName": "ava"
}
]
Attempt #3
searchTechTags(tagName: string): Observable<TechTag[]> {
return this.http.get<TechTag[]>(this.baseUrl).pipe(map(data => data.filter(tags =>
tags.tagName.includes(tagName))));
}
Result #3 (doesn't even work)
ERROR TypeError: tags.tagName.includes is not a function
Attempt #4
searchTechTags(tagName: string): Observable<TechTag[]> {
return this.http
.get<TechTag[]>(this.baseUrl)
.pipe(
map((data) => data.filter(p => p.tagName.indexOf(tagName) !== -1))
)
}
Result #4
ERROR TypeError: p.tagName.indexOf is not a function
Add toString() to tagName before filtering it, because it looks like an object not a string.
map((data) => data.filter(p => p.tagName.toString().indexOf(tagName) !== -1))

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)

Separate an object in a array of objects

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);

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
}
]

Issues with transforming array data

I'm trying to transform the following JSON array data structure -
From
[
{
"date": "2019-01-01",
"marks": [
{
"quantity": {
"shoes": 1,
"belt": 2,
"socks": 3
}
}
]
},
{
"date": "2019-01-02",
"marks": [
{
"quantity": {
"shoes": 4,
"belt": 5,
"socks": 6
}
}
]
}
]
To
rows: [
{
values: [ '2019-01-01', 1, 2, 3]
},
{
values: [ '2019-01-02', 4, 5, 6]
}
]
The code that I was able to try so far is this -
function myFunction() {
var response = [
{
"date": "2019-01-01",
"marks": [
{
"quantity": {
"shoes": 1,
"belt": 2,
"socks": 3
}
}
]
},
{
"date": "2019-01-02",
"marks": [
{
"quantity": {
"shoes": 4,
"belt": 5,
"socks": 6
}
}
]
}
];
var transform = response.map(function(dailyMarks) {
var row = [];
Object.keys(response).asArray().forEach(function (field) {
switch (field) {
case 'shoes':
return row.push(dailyMarks.shoes);
case 'belt':
return row.push(dailyMarks.belt);
case 'socks':
return row.push(dailyMarks.socks);
case 'date':
return row.push(dailyMarks.date);
default:
return row.push('');
}
});
return { values: row };
});
Logger.log(transform);
}
However, I'm running into this error -
TypeError: Cannot find function asArray in object 1,2. (line XX, file "Code")
Pretty sure I'm doing something wrong but have not been able to figure out where.
Objective is simply to transform the aforementioned data structure - approach doesn't really matter.
Any help would be highly appreciated! Thanks.
In ES5,
var arr1 = [
{
date: '2019-01-01',
marks: [
{
quantity: {
shoes: 1,
belt: 2,
socks: 3,
},
},
],
},
{
date: '2019-01-02',
marks: [
{
quantity: {
shoes: 4,
belt: 5,
socks: 6,
},
},
],
},
];
var out = [];
arr1.forEach(function(obj) {
obj.marks.forEach(function(mark) {
out.push({
values: [obj.date].concat(
Object.keys(mark.quantity).map(function(key) {
return mark.quantity[key];
})
),
});
});
});
console.log({ rows: out });
You could take an array of keys for the order and flatmap the marks array.
var data = [{ date: "2019-01-01", marks: [{ quantity: { shoes: 1, belt: 2, socks: 3 } }] }, { date: "2019-01-02", marks: [{ quantity: { shoes: 4, belt: 5, socks: 6 } }] }],
keys = ['shoes', 'belt', 'socks'],
rows = data.map(({ date, marks }) =>
({ values: [date, ...marks.flatMap(({ quantity }) => keys.map(k => quantity[k]))] })),
result = { rows };
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
let x = products.map(p=>{
return p.marks.reduce((t,m)=>{
t.push({ values: [p.date, ...Object.entries(m.quantity).map(([key, value]) => value)]})
return t;
},[])
}
).flat(2)
console.log(x)
var list=[{"date":"2019-01-01","marks":[{"quantity":{"shoes":1,"belt":2,"socks":3}}]},{"date":"2019-01-02","marks":[{"quantity":{"shoes":4,"belt":5,"socks":6}}]}];
let result = list.map(( {date, marks} ) => { return {value: [date, ...Object.values(marks[0].quantity)]};});
let wrap = {rows: result};
console.log(wrap);

Resources