How to convert JSON array from REST API to an object - javascript

From my backend I receive message like this:
[
[
{
"id": 1,
"date": "2018-12-31"
},
{
"id": 12,
"standard": null,
"capacity": 7,
"description": null,
}
],
[
{
"id": 26,
"date": "2018-12-08"
},
{
"id": 11,
"standard": null,
"capacity": 7,
"description": null,
}
]
]
I want to map this response to list of 2 objects, so I created class:
export class Response {
id: string;
date: string;
standard: string;
capacity: number;
description: string;
}
I my method, where I calling a service I tried different methods, and even backendData.forEach doesn't work - Angular doesn't recognize backendData as an array.
getData(){
this.service.getData().subscribe(backendData=>{
//how to convert backendData to an array of Response[]?
})
}
I will be very grateful for every help I have been stuck with this for couple of time.

Maybe it helps
getData(){
this.service.getData().subscribe(backendData=> {
//how to convert backendData to an array of Response[]?
return backendData.map(array => Object.assign(array[0], array[1]))
})
}
I'm not sure that you really can convert to Response type this array, because your id is string, but in response you got number, also you got nullable description and standard in response

Related

How do I patch values back to an object in Angular 13?

I have an issue with patchValue and setValue in Angular 13.
I have a form I created using formBuilder called manageUsers. In it, I have a key called userRoles that contains an array of booleans.
The manageUsers form contains checkboxes for the user roles. The array of booleans turns those checkboxes into checked/unchecked based on the boolean values.
When you first visit the page, the userRoles array in the manageUsers form, by default, look like this...
this.manageUsers.value.userRoles = [false, false, false, false, false]
When a user checks or unchecks a checkbox, the form recognizes a change in state and the "Save Changes" button enables. If someone clicks the "Save Changes" button, then the manageUsers form gets sent to an endpoint where it is saved in a database.
When you select a user, for example "Anthony", the information for that user checks against a list of 5 user roles that looks like this...
[
{
"id": 1,
"name": "AnalyticalAdmin"
},
{
"id": 2,
"name": "Analyst"
},
{
"id": 4,
"name": "AdminReviewer"
},
{
"id": 5,
"name": "SystemAdministrator"
},
{
"id": 6,
"name": "CaseworkSTRTechLeader"
}
]
to see what roles are assigned to Anthony. Let's say "AdminReviewer" is assigned. Then the resulting userRoles array would look like this...
this.manageUsers.value.userRoles = [false, false, true, false, false]
That means the third checkbox ("AdminReviewer") would be appear checked in the form and the others would not be checked. So let's say then you were to check the second checkbox ("Analyst"). The updated userRoles in the manageUsers form would look like this...
this.manageUsers.value.userRoles = [false, true, true, false, false]
What I've done is written code to compare that array with the list of 5 roles above.
The resulting array looks like this...
[
{
"id": 2,
"name": "Analyst"
},
{
"id": 4,
"name": "AdminReviewer"
}
]
So far so good.
Here's my problem...
When I go to patch that array of objects BACK INTO the manageUsers form, the result looks like this...
[
{
"id": 2,
"name": "Analyst"
},
{
"id": 4,
"name": "AdminReviewer"
},
true,
false,
false
]
Angular, for some reason, wants to add booleans to make up for the three missing elements. But here's the thing, I ONLY WANT the this.manageUsers.value.userRoles form object to contain the two objects. I don't need the superfluous booleans.
I just want the this.manageUsers.value.userRoles object (that I'm sending back to the database) to look like this...
[
{
"id": 2,
"name": "Analyst"
},
{
"id": 4,
"name": "AdminReviewer"
}
]
NOT LIKE THIS...
[
{
"id": 2,
"name": "Analyst"
},
{
"id": 4,
"name": "AdminReviewer"
},
true,
false,
false
]
I've tried using BOTH .patchValue and .setValue methods, but they don't work.
How do I patch an array of objects and tell Angular to NOT include booleans for the roles I didn't want to account for?
*UPDATED...
Here is the code I use set the userRoles array...
this.manageUsers = this.formBuilder.group({
id: null,
firstName: ['', Validators.required],
lastName: ['', Validators.required],
userInitial: ['', Validators.required],
netUserName: ['', Validators.required],
workPhone: [null, [Validators.required, Validators.pattern("[0-9 ]{10}")]],
email: ['', Validators.required],
userTitle: ['', Validators.required],
userRoles: new FormArray([], Validators.required),
incidents: new FormArray([], Validators.required)
})
Then, I created a property called userRolesArray...
public get userRolesArray() {
return this.manageUsers.controls.userRoles as FormArray;
}
Then, I created a property called addCheckboxesToManageUsers() and call that in the ngInit() method.
private addCheckboxesToManageUsers(): void {
this.listOfUserRoles.forEach(() => this.userRolesArray.push(new FormControl(false)));
}
after getting value from this.manageUsers.value.userRoles use reducer to remove all boolean type of value.
const data = [
{
"id": 2,
"name": "Analyst"
},
{
"id": 4,
"name": "AdminReviewer"
},
true,
false,
false
]
const newArr = data.reduce((prev, curr) => {
if (typeof curr !== 'boolean') prev.push(curr);
return prev;
}, []);
console.log(newArr)
updated one-liner
data.filter(data => typeof data != 'boolean')

How to get JSON entry from returned objects

I got JSON data, like:
{
"id": 1,
"active": true,
"dependency": [
{ "id": 2 }
{ "id": 3 }
]
},
{
"id": 2,
"active": true
},
{
"id": 3,
"active": true
}
I want to retrieve the "active" value for each dependency in the id 1 object. So far I used a forEach to get those dependency.
thisElement.dependency.forEach(function(id) {
console.log(id)
}
Which returns id 2 and id 3 as objects. Is there a way to use id.active straight away? By using only one loop? Because the result so far are objects without any connection to the related JSON data. Would it require to loop through the whole JSON data to retrieve those values?
The most efficient thing to to is create a hashmap with an Object or Map first so you only need to iterate the array once to find dependency related values.
You could do it by using Array#find() to search whole array each time but that is far more time complexity than the o(1) object lookup
const activeMap = new Map(data.map(obj => [obj.id, obj.active]))
data[0].dependency.forEach(({id}) => console.log(id ,' active: ' , activeMap.get(id)))
<script>
const data =
[
{
"id": 1,
"active": true,
"dependency": [
{"id": 2 },
{"id": 3}
]
},
{
"id": 2,
"active": false
},
{
"id": 3,
"active": true
}
]
</script>

Dynamically add array elements to JSON Object

I'm creating a JSON object from an array and I want to dynamically push data to this JSON object based on the values from array. See my code for a better understanding of my problem...
for(i=0;i<duplicates.length; i++) {
var request = {
"name": duplicates[i].scope,
"id": 3,
"rules":[
{
"name": duplicates[i].scope + " " + "OP SDR Sync",
"tags": [
{
"tagId": 1,
"variables":[
{
"variable": duplicates[i].variable[j],
"matchType": "Regex",
"value": duplicates[i].scopeDef
}
],
"condition": false,
},
{
"tagId": 1,
"condition": false,
}
],
"ruleSetId": 3,
}
]
}
}
I take object properties from the duplicates array that can have the following elements:
[{scopeDef=.*, scope=Global, variable=[trackingcode, v1, v2]}, {scopeDef=^https?://([^/:\?]*\.)?delta.com/products, scope=Products Section, variable=[v3]}]
As you can see, an object contain variable element that can have multiple values. I need to push to the JSON object all those values dynamically (meaning that there could be more than 3 values in an array).
For example, after I push all the values from the duplicates array, my JSON object should look like this:
name=Products Section,
rules=
[
{
name=Products Section OP SDR Sync,
tags=[
{
variables=
[
{
matchType=Regex,
variable=v3,
value=^https?://([^/:\?]*\.)?delta.com/products
},
{
matchType=Regex,
variable=trackingcode,
value=.*
},
{
matchType=Regex,
variable=v1,
value=.*
},
{
matchType=Regex,
variable=v2,
value=.*
}
],
condition=false,
},
{
condition=false,
tagId=1
}
],
ruleSetId=3
}
]
}
I tried the following code but without success:
for(var j in duplicates[i].variable) {
var append = JSON.parse(request);
append['variables'].push({
"variable":duplicates[i].variable[j],
"matchType": "Regex",
"value": duplicates[i].scopeDef
})
}
Please let me know if I need to provide additional information, I just started working with JSON objects.
First of all, you dont need to parse request, you already create an object, parse only when you get JSON as string, like:
var json='{"a":"1", "b":"2"}';
var x = JSON.parse(json);
Next, you have any property of object wrapped in arrays. To correctly work with it you should write:
request.rules[0].tags[0].variables.push({
"variable":duplicates[i].variable[j],
"matchType": "Regex",
"value": duplicates[i].scopeDef
})
If you want to use your code snippet, you need some changes in request:
var request = {
"name": duplicates[i].scope,
"id": 3,
"variables":[
{
"variable": duplicates[i].variable[j],
"matchType": "Regex",
"value": duplicates[i].scopeDef
}
],
"rules":[
{
"name": duplicates[i].scope + " " + "OP SDR Sync",
"tags": [
{
"tagId": 1,
"condition": false,
},
{
"tagId": 1,
"condition": false,
}
],
"ruleSetId": 3,
}
]
}
}
To understand JSON remember basic rule: read JSON backward. It means:
property
object.property
arrayOfObfects['id'].object.property
mainObject.arrayOfObfects['id'].object.property
and so on. Good luck!

Angular or JavaScript to format/beautify JSON

I'm trying to figure out how to format this json in angular this is the result from extending all models from multiple forms.
{
"identifications": {},
"insurances": [
{
"insurances": [
{
"category": "",
"compName": "",
"planType": "",
"note": ""
}
]
}
],
"medical": {
"doctors": [
{
"doctors": [
{
"firstname": "James"
"note": "James Bond Note"
},
{
"firstname": "Robin",
"note": "Lorem Ipsum Dolor"
}
]
}
],
"records": {}
}
Here's I need to achieve to insert it into the API.
{
"parent_id": 17,
"insurances": [{
"insurance_type": "",
"notes": ""
}],
"medical": {
"doctors": {},
"blood": {},
},
"records": {}
}
If you're really looking at just pretty-printing stuff, investigate JSON.stringify:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
If you're trying to change the object from one data representation to another (I'll note that the second object is structurally different from the first, not just a matter of whitespace), then you just need to write some javascript that does stuff like new.doctors = old[0].medical[1].doctors (example, not actual code)
This question is pretty old, but nowadays you should use the json filter. For example:
var data = {a: 1, b: 2};
Then in the template:
{{ data|json:2 }}
Should output
{
a: 1,
b: 2
}

How do I chain "SelectMany" calls with linqjs (or flatten JSON)

Using linq.js how can I chain two SelectMany calls together.
Given the following JSON structure:
[
{
"UpFrontCost": "29.95",
"Currency": "USDAUD",
"FittingDate": "2013-07-08 06:30:16Z",
"Widgets": [
{
"ID": 3,
"Name": "Test1"
},
{
"ID": 4,
"Name": "Test19"
},
{
"ID": 6,
"Name": "Test8"
}
]
},
{
"UpFrontCost": "29.95",
"Currency": "USDAUD",
"FittingDate": "2013-07-08 06:30:16Z",
"Widgets": [
{
"ID": 67,
"Name": "Test1"
},
{
"ID": 99,
"Name": "Test19"
},
{
"ID": 34,
"Name": "Test8"
}
]
}
]
I would like a list of all the "Widgets" (in this example a list of 6 widgets).
You don't need to really chain anything. Your root object is an array, you just want to select each widget for each object in that array.
var query = Enumerable.From(jsonObject)
.SelectMany("$.Widgets") // Select each widget found in the Widgets property
.ToArray();
To flatten that array of widgets attaching each property of the parent object to the result, there's a couple of ways you could do it. You can use a nested query using the function syntax.
var query = Enumerable.From(jsonObject)
.SelectMany(function (item) {
return Enumerable.From(item.Widgets)
.Select(function (widget) {
return {
ID: widget.ID,
Name: widget.Name,
UpFrontCost: item.UpFrontCost,
Currency: item.Currency,
FittingDate: item.FittingDate
};
});
})
.ToArray();
Or using the lambda string syntax:
var query = Enumerable.From(items)
.SelectMany("$.Widgets",
// argument 1 ($) - the parent object
// argument 2 ($$) - the selected object (a widget)
"{ ID: $$.ID, Name: $$.Name, UpFrontCost: $.UpFrontCost, Currency: $.Currency, FittingDate: $.FittingDate }"
)
.ToArray();

Categories

Resources