I would like to store every arrivalDate in my array list.
Someone could tell me how can I do it?
But my array is still empty.
JSON returned by the API:
{
"reservations": {
"reservationInfo": [
{
"roomStay": {
"arrivalDate": "11am"
},
"WeatherR": {
"sound": "cloudy"
},
},
{
"roomStay": {
"arrivalDate": "7pm"
},
"WeatherR": {
"sound": "cloudy"
},
}
]
}
}
component.ts
searchForReservation() {
alert('hello');
this.http.get('/api/searchForReservation')
.subscribe((data) => {
this.ddataIno = data;
this.ddataIno = this.ddataIno.result.reservations.reservationInfo;
console.log('number of value', this.ddataIno.length);
console.log('content', this.ddataIno);
for (let i = 0; i <= this.ddataIno[i].length; i++) {
this.list = this.ddataIno.roomStay.arrivalDate;
}
console.log('store array', this.list)
})
}
searchForReservation() {
alert('hello');
this.http.get('/api/searchForReservation')
.subscribe((data) => {
const reservationInfo = this.data.result.reservations.reservationInfo;
this.list = reservationInfo.map(e => e.roomStay.arrivalDate);
})
}
Here's a working example in vanilla JS. You would need to make some small adjustments for angular, like this.list = ... instead of let list = ...
Using Array#map, you can create a new array from the JSON object
data.reservations.reservationInfo.map(r => r.roomStay.arrivalDate)
let data = {
"reservations": {
"reservationInfo": [{
"roomStay": {
"arrivalDate": "11am"
},
"WeatherR": {
"sound": "cloudy"
},
},
{
"roomStay": {
"arrivalDate": "7pm"
},
"WeatherR": {
"sound": "cloudy"
},
}
]
}
}
// declare your list as an array at the top
// list: []
// below would start off as 'this.list'
let list = data.reservations.reservationInfo.map(r => r.roomStay.arrivalDate);
console.log(list);
Your for loop is just reassigning the value of this.list
I suggest reading up on Array methods
I would use a map method, e.g.
this.list = this.ddataIno.result.reservations.reservationInfo.map(i => i.roomStay.arrivaldate);
Related
I am receiving this JSON from my backend and i need to work out the count of "concrete_compressive_cylinder_100"'s where picked_up = false
concrete_samples (can be multiple per work order) can be null ( key is always present )
sample_specimens ( 1 per concrete_sample) can be null ( key is always present )
concrete_compressive_cylinder_100 ( null to 500 per sample_specimens )
{
"uuid":"4ad7bfe1-48d6-488c-bfaf-33f7189a41d7",
"org_workorder_id":1000,
"concrete_samples":[
{
"uuid":"776a8ccb-82fd-4a42-a6eb-8f286a4a9c0b",
"workorder_uuid":"4ad7bfe1-48d6-488c-bfaf-33f7189a41d7",
"org_sample_id":5001,
"sample_specimens":{
"concrete_compressive_cylinder_100":[
{
"uuid":"b9ef3a8a-2945-41e6-a34d-d90d1bd64819",
"sample_uuid":"776a8ccb-82fd-4a42-a6eb-8f286a4a9c0b",
"picked_up":true
},
{
"uuid":"d43f15b3-2208-43de-8fff-8d237c6918f9",
"sample_uuid":"776a8ccb-82fd-4a42-a6eb-8f286a4a9c0b",
"picked_up":true
},
{
"uuid":"472f832a-6f07-4af6-97ea-e6dc7b9b3799",
"sample_uuid":"776a8ccb-82fd-4a42-a6eb-8f286a4a9c0b",
"picked_up":true
}
],
"concrete_compressive_cylinder_200":[
{
"uuid":"d659d058-e4ec-4f72-9d73-9ea98295715a",
"sample_uuid":"776a8ccb-82fd-4a42-a6eb-8f286a4a9c0b",
"picked_up":true
},
{
"uuid":"777372e0-3e58-4292-bae4-bec84dfe1402",
"sample_uuid":"776a8ccb-82fd-4a42-a6eb-8f286a4a9c0b",
"picked_up":true
},
{
"uuid":"f63f7102-7673-4e71-97e5-2d85e0c1a93d",
"sample_uuid":"776a8ccb-82fd-4a42-a6eb-8f286a4a9c0b",
"picked_up":true
}
]
}
},
{
"uuid":"61138cf3-0c49-4495-8a89-533c0a6e50bc",
"workorder_uuid":"4ad7bfe1-48d6-488c-bfaf-33f7189a41d7",
"org_sample_id":5002,
"sample_specimens":{
"concrete_compressive_cylinder_100":null,
"concrete_compressive_cylinder_200":null
}
}
]
}
I've gotten this far but it dosen't really work and now im more confused some guidance would be great
const out = res.data.concrete_samples.reduce((acc, sample) => {
const { sample_specimens } = sample;
const concrete_compressive_cylinder_100 = Object.keys(sample_specimens)["concrete_compressive_cylinder_100"];
const specimens = concrete_compressive_cylinder_100.map(obj => {
obj.picked_up ? console.log("picked up") : console.log("Not pickedn up")
});
}, []);
Array.prototype.reduce accepts a function whose return value is eventually returned from reduce itself. The function is passed each element of the array, along with the value accumulated so far. For example,
[1, 2, 3].reduce((accumulator, element) => accumulator + element)
// => 6
You can also provide an initial value, which will be passed to your function as accumulator on the first iteration.
At a basic level, to count how many occurrences of an object with a certain property with reduce, you could use something like this,
let array = [
{ foo: 4 },
{ foo: 6 },
{ bar: 8 },
]
array.reduce((count, element) => {
if (element.foo !== undefined) {
return count + 1
} else {
return count
}
}, 0)
// => 2
Extending this to your code (with extraneous data elided), with a nested reduce to get the count of cylinders with the desired picked_up property,
const data = {
"concrete_samples":[
{
"sample_specimens":{
"concrete_compressive_cylinder_100":[
{
"picked_up":true
},
{
"picked_up":true
},
{
"picked_up":true
}
],
"concrete_compressive_cylinder_200":[
{
"picked_up":true
},
{
"picked_up":true
},
{
"picked_up":true
}
]
}
},
{
"sample_specimens":{
"concrete_compressive_cylinder_100":null,
"concrete_compressive_cylinder_200":null
}
}
]
}
const result = data.concrete_samples.reduce((count, sample) => {
const cylinders = sample.sample_specimens.concrete_compressive_cylinder_100
if (cylinders == null) {
return count
}
const samplePickedUpCount = cylinders.reduce((pickedUpCount, cylinder) => {
if (cylinder.picked_up) {
return pickedUpCount + 1
} else {
return pickedUpCount
}
}, 0)
return count + samplePickedUpCount
}, 0)
console.log(result)
You could also use Array.prototype.filter to accomplish the same thing, getting an array of the cylinders with the desired property, and getting the length of that array.
If I understand correctly, you'd like to obtain a new concrete_samples array where the array values of nested sample_specimens objects are reduced to the number of items where picked_up is true - one approach to that would be as documented in the following snippet:
const data={"uuid":"4ad7bfe1-48d6-488c-bfaf-33f7189a41d7","org_workorder_id":1000,"concrete_samples":[{"uuid":"776a8ccb-82fd-4a42-a6eb-8f286a4a9c0b","workorder_uuid":"4ad7bfe1-48d6-488c-bfaf-33f7189a41d7","org_sample_id":5001,"sample_specimens":{"concrete_compressive_cylinder_100":[{"uuid":"b9ef3a8a-2945-41e6-a34d-d90d1bd64819","sample_uuid":"776a8ccb-82fd-4a42-a6eb-8f286a4a9c0b","picked_up":true},{"uuid":"d43f15b3-2208-43de-8fff-8d237c6918f9","sample_uuid":"776a8ccb-82fd-4a42-a6eb-8f286a4a9c0b","picked_up":true},{"uuid":"472f832a-6f07-4af6-97ea-e6dc7b9b3799","sample_uuid":"776a8ccb-82fd-4a42-a6eb-8f286a4a9c0b","picked_up":true}],"concrete_compressive_cylinder_200":[{"uuid":"d659d058-e4ec-4f72-9d73-9ea98295715a","sample_uuid":"776a8ccb-82fd-4a42-a6eb-8f286a4a9c0b","picked_up":true},{"uuid":"777372e0-3e58-4292-bae4-bec84dfe1402","sample_uuid":"776a8ccb-82fd-4a42-a6eb-8f286a4a9c0b","picked_up":true},{"uuid":"f63f7102-7673-4e71-97e5-2d85e0c1a93d","sample_uuid":"776a8ccb-82fd-4a42-a6eb-8f286a4a9c0b","picked_up":true}]}},{"uuid":"61138cf3-0c49-4495-8a89-533c0a6e50bc","workorder_uuid":"4ad7bfe1-48d6-488c-bfaf-33f7189a41d7","org_sample_id":5002,"sample_specimens":{"concrete_compressive_cylinder_100":null,"concrete_compressive_cylinder_200":null}}]};
const concreteSamplesResult = data.concrete_samples.map(sample => {
// Iterate each key/value entry of sample_specimens, and reduce to a new
// specimens object that contains counts of picked_up: true items in sub array
const sample_specimens = Object
.entries(sample.sample_specimens)
.reduce((specimens, entry) => {
// Calculate count of picked_up items for arr of this entry
const [key, arr] = entry;
const count = Array.isArray(arr) ?
arr.reduce((total, item) => (total + (item.picked_up ? 1 : 0)), 0) : 0;
// Add count for entry key to newly reduced sample_specimen object
return { ...specimens, [key] : count };
},{})
return { ...sample, sample_specimens };
});
console.log(concreteSamplesResult);
Check null > loop > check null > loop and count isn't it?
function someFunc(json) {
const { concrete_samples } = json;
if (!concrete_samples) return;
let numberOFAvailableCylinder100s = 0;
const doSomethingWithCylinder = cylinder => {
console.log(cylinder.uuid);
numberOFAvailableCylinder100s += 1;
}
concrete_samples.forEach(concrete_sample => {
const { sample_specimens } = concrete_sample;
if (!sample_specimens) return;
findAvailableCylinder100(sample_specimens, doSomethingWithCylinder);
})
console.log(`count: ${numberOFAvailableCylinder100s}`);
}
function findAvailableCylinder100(sample_specimens, callback) {
const { concrete_compressive_cylinder_100 } = sample_specimens;
if (!concrete_compressive_cylinder_100) return;
concrete_compressive_cylinder_100.forEach(cylinder => {
if (!cylinder.picked_up) callback(cylinder);
});
}
someFunc(yourJSONObject);
How can I find something through some arrays that also contain an array?
To be more precisely:
And I want to return from the coaches array, the id(within the coaches) that matches the username. What I've tried:
if (!(args['coach'].value === '') && (args['coach'].value !== null)) {
coachId = this.items.find(x => x.username === args.coach.value).id;
}
Basically this.items is what I've console.log before. Now it gives me undefined.
Has someone a fix for this? Thank you very much.
[
{
"id":584,
"name":"Name",
"coaches":[
{
"id":8587,
"username":"test"
},
{
"id":8589,
"username":"test1"
}
]
},
{
"id":587,
"name":"O1",
"coaches":[
]
}
]
And let s say I want to return the id 8587 when searching for the name test.
Combine map and find:
const array = [
[{a1: 1},
{a2: 2}
],
[{a1: 1},
{a2: 2},
{a3: 3}]
];
const element = array.map(innerArray => {
const found = innerArray.find(el => el.a1 === 1);
if (found) return found.a1;
return null;
}).find(el => el !== null);
console.log(element) // 1
For finding multiple matches do as follows:
const data = [{
"id": 584,
"name": "Name",
"coaches": [{
"id": 8587,
"username": "test"
},
{
"id": 8589,
"username": "test1"
}
]
},
{
"id": 587,
"name": "O1",
"coaches": [
]
}
];
const usernameToSearch = 'test1';
const foundCoachIds = data
.reduce((acc, curr) => {
// Destructure the coaches property first
const {
coaches,
...rest
} = curr;
// Check if any username matches the coach
const foundMatches = coaches.filter(x => x.username === usernameToSearch);
// If there is any found match push into accumulator
if (foundMatches.length) {
for (const foundMatch of foundMatches) {
if (acc.indexOf(foundMatch.id) === -1) {
acc.push(foundMatch.id);
}
}
}
return acc;
}, []);
console.log(foundCoachIds);
let y = this.items.filter(o => o.coaches.some(e => e.username === 'test'))[0]
.coaches.filter(e=>e.username === 'test')[0].id;
console.log(y);
const data = [
{
"id":584,
"name":"Name",
"coaches":[
{
"id":8587,
"username":"test"
},
{
"id":8589,
"username":"test1"
}
]
},
{
"id":587,
"name":"O1",
"coaches":[
]
}
];
For outer id
data.map(it => {return !!it.coaches.find(it2 => it2.username == "test") ? it.id : null}).filter(it=>!!it)
evaluates to [584]
For inner
(coaches) id:
data.map(it => it.coaches.find(it2 => it2.username == "test")).filter(it => !!it).map(it=> it.id)
returns [8587]
Just need to take the first item from these to get your answer.
There was such a problem.
I'm trying to make a certain number of GET requests in Wikipedia API using a cycle.
Trying to do this with the function getAllInfo()
articles.components.ts
export class ArticlesComponent {
constructor(private articlesServices: ArticlesService) { }
#Input() allTitles: string[];
articlesInfo: ArticleInformationNew;
allArray: [[string, number]] = [['', 0]];
static getUrlInformation(searchQuery: string) {
return 'https://ru.wikipedia.org/w/api.php?action=query&titles='
+ searchQuery + '&prop=info&format=json&origin=*';
}
getAllInfo() {
for (const title of this.allTitles) {
this.articlesServices.getArticleInformation(ArticlesComponent.getUrlInformation(title))
.subscribe(
(data: ArticleInformation) => this.articlesInfo = {
...data,
query: { pages: [Object.values(data.query.pages)[0]]}}
);
this.allArray.push([this.articlesInfo.query.pages[0].touched, this.articlesInfo.query.pages[0].length]);
}
}
}
articles.service.ts
export interface ArticleInformation {
batchComplete: string;
query: {
pages: {
}
};
}
export interface ArticleInformationNew {
batchComplete: string;
query: {
pages: any[]
};
}
export class ArticlesService {
constructor(private http: HttpClient) { }
getArticleInformation(url) {
return this.http.get<ArticleInformation>(url);
}
}
An array this.allTitles can consist of a number of lines. For example: this.allTitles = ['Naumen', 'Naumen DMS']
I expect that the arraythis.allArray will be two-dimensional and contain arrays that consist of rows with data for each query. For example:
this.allArray[0] = ['', 0]
this.allArray[1] = ['2019-02-01T23:27:26Z', 3687]
this.allArray[2] = ['2019-01-21T04:24:21Z', 9704]
But in fact, it turns out that each element of a two-dimensional array is the same. For example:
this.allArray[0] = ['', 0]
this.allArray[1] = ['2019-02-01T23:27:26Z', 3687]
this.allArray[2] = ['2019-02-01T23:27:26Z', 3687]
Why and how to fix it?
Try this,
getAllInfo() {
for (const title of this.allTitles) {
this.articlesServices.getArticleInformation(ArticlesComponent.getUrlInformation(title))
.subscribe(
(data: ArticleInformation) => {
this.articlesInfo = {
...data,
query: { pages: [Object.values(data.query.pages)[0]]}
}
this.allArray.push([this.articlesInfo.query.pages[0].touched,this.articlesInfo.query.pages[0].length]);
}
);
}
}
You can use combineLatest: https://www.learnrxjs.io/operators/combination/combinelatest.html
First, collect observables to be combined (but without subscribing to them), then combine them with combineLatest and get the response as an array and iterate over it.
getAllInfo() {
console.log(this.allTitles);
observablesToSubscribe = [];
for (const title of this.allTitles) {
observablesToSubscribe.push(this.articlesServices.getArticleInformation(ArticlesComponent.getUrlInformation(title)));
}
combineLatest(observablesToSubscribe).subscribe((responseData: Array<ArticleInformation>) => {
responseData.forEach((responseDatum) => {
this.allArray.push({
...data,
query: { pages: [Object.values(data.query.pages)[0]]}
})
});
});
}
Maybe, I misunderstood the question, but you can get pages with particular titles, by correcting your searchQuery (using alternative separators for titles), and get rid of for loop:
getAllInfo() {
console.log(this.allTitles);
this.articlesServices.getArticleInformation(
ArticlesComponent.getUrlInformation(this.allTitles.join('|'))
.subscribe(
(res => {
// here is a result with all pages of particular titles,
// then you can process your result...
console.log(res);
// this.allArray is a multidimensional array
// [["2019-01-25T00:45:06Z",4508],
// ["2019-01-26T07:25:08Z", 773]]
this.allArray = Object.keys(res.query.pages)
.reduce((acc, val, index) => {
acc[index] = [pages[val].touched, pages[val].length];
return acc;
}, []);
});
}
searchQuery for titles will be in that case Naumen | Naumen DMS (not, for example, just Naumen). | (pipe) is an alternative separator for titles.
To process the result (res.query.pages):
const pages = {
"755288": {
"pageid": 755288,
"ns": 0,
"title": "Spring",
"contentmodel": "wikitext",
"pagelanguage": "ru",
"pagelanguagehtmlcode": "ru",
"pagelanguagedir": "ltr",
"touched": "2019-01-26T07:25:08Z",
"lastrevid": 84434967,
"length": 773
},
"92586": {
"pageid": 92586,
"ns": 0,
"title": "Atom",
"contentmodel": "wikitext",
"pagelanguage": "ru",
"pagelanguagehtmlcode": "ru",
"pagelanguagedir": "ltr",
"touched": "2019-01-25T00:45:06Z",
"lastrevid": 95248014,
"length": 4508
},
};
const arr = Object.keys(pages).reduce((acc, val, index) => {
acc[index] = [pages[val].touched, pages[val].length];
return acc;
}, []);
console.log(arr);
I don't think this is difficult, I just can't figure out the best way to do it. This function is creating an array, from a group of checkboxes. I then want to break up the array and create an array of objects, because each object can have corresponding data. How do I filter out existing rolesInterestedIn.roleType.
handleTypeOfWorkSelection(event) {
const newSelection = event.target.value;
let newSelectionArray;
if(this.state.typeOfWork.indexOf(newSelection) > -1) {
newSelectionArray = this.state.typeOfWork.filter(s => s !== newSelection)
} else {
newSelectionArray = [...this.state.typeOfWork, newSelection];
}
this.setState({ typeOfWork: newSelectionArray }, function() {
this.state.typeOfWork.map((type) => {
this.setState({
rolesInterestedIn: this.state.rolesInterestedIn.concat([
{
roleType: type,
}
])
}, function() {
console.log(this.state.rolesInterestedIn);
});
})
});
}
UDPATE
rolesInterestedIn: [
{
roleType: '',
experienceYears: ''
}
],
Because each time you do setState you are concatenating the new value to the prev one in rolesInterestedIn array. Add new value only when you are adding new item, otherwise remove the object from both the state variable typeOfWork and rolesInterestedIn.
Try this:
handleTypeOfWorkSelection(event) {
const newSelection = event.target.value;
let newSelectionArray, rolesInterestedIn = this.state.rolesInterestedIn.slice(0);
if(this.state.typeOfWork.indexOf(newSelection) > -1) {
newSelectionArray = this.state.typeOfWork.filter(s => s !== newSelection);
rolesInterestedIn = rolesInterestedIn.filter(s => s.roleType !== newSelection)
} else {
newSelectionArray = [...this.state.typeOfWork, newSelection];
rolesInterestedIn = newSelectionArray.map((workType) => {
return {
roleType: workType,
experienceYears: '',
}
});
}
this.setState({
typeOfWork: newSelectionArray,
rolesInterestedIn: rolesInterestedIn
});
}
Suggestion: Don't use multiple setState within a function, do all the calculation then use setState once to update all the values in the last.
I would like to add an array into an array object. However, I am only able to add the array into a new object instead of the existing one. Is there any way where I can link the array to the existing object? Its much more easier for me too if I could add in the array based on which link it is from.
Here is my code:
this.af.database.list(`/users/${userid}/favourites`, {
query: { orderByChild: 'priority' },
preserveSnapshot: true
})
.subscribe(snapshots => {
snapshots.forEach(snapshot => {
this.category.push({
name: snapshot.val().name,
rss: snapshot.val().regions[0].rss
});
})
for (let i = 0; i < this.category.length; i++) {
this.http.get(this.category[i].rss)
.map(res => res.text())
.subscribe((data) => {
this.parseXML(data)
.then((data) => {
this.xmlItemsApac = data
this.category.push({
feeds: data
})
});
});
}
});
console.log(this.category)
parseXML(data) {
return new Promise(resolve => {
var k,
arr = [],
parser = new xml2js.Parser(
{
explicitArray: false
});
parser.parseString(data, function (err, result) {
var obj = result.rss.channel;
for (k in obj.item) {
var item = obj.item[k];
arr.push({
title: item.title,
link: item.link,
description: item.description,
pubDate: item.pubDate
});
}
resolve(arr);
});
});
}