How to print json array in angular - html

Here Stackblitz https://stackblitz.com/edit/angular-parse-object
Response format from REST API is
[{"id":123,"name":Test,"value":{"pass": true, "verified": true}}, {"id":435,"name":Test12,"value":{"pass": false, "verified": true}},]
<div *ngFor="let record of student.value">
<ul *ngFor="let key of objectKeys(record)">
<li>{{key}} :: {{record[key]}}</li>
</ul>
</div>
Getting error ** Cannot read property 'value' of undefined **
<div *ngFor="let rec of student">
<h2>{{rec.id}}</h2>
<div *ngFor="let result of rec.value">
<h4> {{value.pass}} </h4>
</div>
</div>
getting Error object of type 'string'. NgFor only supports binding to Iterables such as Arrays.
How to fix it?
I expect the output as
ID : 123 Name : Test Pass : true [yes] verified : true

I just write a basic ngFor code using your Student Array. Try this I hope it'll help you out. Thanks
HTML
<div class="studentList" *ngFor="let student of students">
<ul>
<li>ID : {{student.id}}</li>
<li>Name : {{student.name}}</li>
<li>Pass : {{student.value.pass}} [{{student.value.pass ? 'Yes' : 'No'}}]</li>
<li>Verified : {{student.value.verified}}</li>
</ul>
</div>
TS
students = [
{
"id":123,
"name":"Test",
"value":{"pass": true, "verified": true}
}, {
"id":435,
"name":"Test12",
"value":{"pass": false, "verified": true}
}
]
CSS
.studentList ul {
list-style: none;
margin: 0 0 10px;
padding: 0;
}
.studentList ul li {
display: inline-block;
margin-right: 10px;
}

You only need 1 ngFor, your value is not array.
<div *ngFor="let rec of student">
<h2>Id: {{rec.id}} Name: {{rec.name}} Pass: {{rec.value.pass}} Verified: {{rec.value.verified}}</h2>
</div>
Reference (you can format it)
https://stackblitz.com/edit/angular-iterator
Updated:
Change your map function with JSON.parse like this
this.student = ["{pass: true, verified: true}", "{pass: false, verified: true}"];
this.student = this.student.map(c=>JSON.parse(c.replace(/([a-zA-Z0-9-]+): ([a-zA-Z0-9-]+)/g, "\"$1\":\"$2\"")));
https://stackblitz.com/edit/angular-parse-object

Related

VueJS Vuelidate and deep nested Array/objects

hope someone can help me I'm working on this since 2 days. I have the following Data in my component:
var types = [
{
**required**: true,
agreements: [
{ selected: true, desc: 'red' },
{ selected: false, desc: 'green'}
]
},
{
required: false,
agreements: [
{ selected: false, desc: 'red' },
{ selected: false, desc: 'green'}
]
},
];
I want to validate all the checkboxes (they have v-model on this selected attributes here!), to be checked, if the parent value required (see my data required!) is true. My Validations looks like this but I miss a last little bit of help to get this required value into my validator selected requiredIf function.
validations: {
types: {
$each: {
agreements: {
$each: {
selected: {
requiredIf: (value) => value === value.parent.required
}
}
}
}
}
}
Hope you understand me right. My Template looks like this:
<div class="mb-3" v-for="type in agreementTypes" :key="type.id">
<h3 class="text-primary">{{ type.displayName }}</h3>
<ul class="list-unstyled">
<li v-for="agreement in type.agreements" :key="agreement.id">
<p>{{ agreement.description }}</p>
<div class="mb-3 form-check form-switch">
<input
class="form-check-input"
type="checkbox"
role="switch"
:checked="agreement.active"
:id="agreement.id"
:required="agreement.required"
v-model="agreement.selected"
/>
<label class="form-check-label" for="agreements">{{ agreement.label }}<span v-if="agreement.required">**</span></label>
</div>
</li>
</ul>
</div>
Any Help will be apreshiated!
bye,
Marcel

Angular2 Unable to print JSON Nested array

Angular2 Unable to print JSON Nested array
help me with nested array problem. Unable to print User_name, User_id and User IRN..
My Component.ts
this.apiService.getIM().subscribe((getIM) => {
this.iOverview = getIM['message'];
console.log(this.iOverview); //This print the whole array.
});
HTML Code
<tr *ngFor="let iUsers of iOverview?.response?.i_details?.user_details | slice:0:10;">
<td>
<div>
<a href="javascript:void(0)"
class="text-default font-weight-semibold letter-icon-title">{{ iUsers.user_name }}</a>
</div>
</div>
</td>
</tr>
My Json Output
{
"message": {
"response": {
"res_type": "IM Users", //able to print this value
"acc_id": "1234567890",
"i_details": [
{
"user_details": [
[
{
"user_name": "admins", //not able to print this value.
"user_id": "MyGroups1",
"user_arn": "user:763526717345"
}
]
]
}
]
}
}
}
Have you noticed that the properties you are trying to access are nested in another array? "user_details": [[...]]. Try accessing it like this:
*ngFor="let iUsers of iOverview?.response?.i_details?.user_details[0]
Hope it helps!

how to display data with *ngFor

i trying to display data with *ngFor, but for some reason this doesn't display any data, and any error.
I already tried alot of samples that i found in internet, none of those worked so i decide to ask here.
here is what i have:
ts file:
public querySuccess: any[];
this.userService.getMentions().subscribe(
(returnAPI) => {
this.querySuccess = returnAPI.data;
});
my html:
<div *ngIf="returnAPI">
<div *ngFor="let key of querySuccess">
<div>{{querySuccess.firstName}}</div>
</div>
</div>
<div *ngIf="!returnAPI">
<div>0 results found!</div>
</div>
the getMentions().subscribe() return this Json:
{
total: 3,
data:[
{userId: 0, firstName: "test", lastName: "xzy"},
{userId: 0, firstName: "john", lastName: "yeet"},
{userId: 0, firstName: "jamal", lastName: "abc"}]
}
You don't need that if condition to loop that ngFor.If its to show that no data error message use querySuccess because returnAPI does not seems to defined anywhere.
<div *ngIf="querySuccess">
<div *ngFor="let key of querySuccess">
<div>{{key.firstName}}</div>//key is single istance queryselector is full array.
</div>
</div>
<div *ngIf="!querySuccess">
<div>0 results found!</div>
</div>
you can try like this
<div *ngIf="returnAPI">
<div *ngFor="let key of querySuccess">
<div>{{key.firstName}}</div> <!-- key instead of querySuccess -->
</div>
</div>
Hi i would firstly recommend you put your code in a function like
ngOnInit() {
this.getAllQueries();
}
getAllQueries() {
this.userService.getMentions().subscribe(
(returnAPI) => {
this.querySuccess = returnAPI.data;
return this.querySuccess;
});
}
make sure you call this in the ngOninit function or your constructor

Angular 8 Nested Object Interpolation

This is my version of Angular CLI:
Angular CLI: 7.3.9
Node: 12.2.0
OS: win32 x64
Angular: 8.0.2
While making an Angular 8 application, I am trying to use nested FormGroups which correspond to the following object:
const Boilerplate: any = {
1: {
desc: "section1",
content: {
1: "question 1.a:",
2: "question 1.b:",
3: "question 1.c"
}
},
2: {
desc: "section2",
content: {
4: "question 2.a:",
5: "question 2.b:",
6: "question 2.c",
7: "question 2.d"
}
}
}
There is an inner FormGroup of FormControls for section 1 and section 2, and an outer FormGroup holding the two inner formgroups. This is defined in the component.ts.
In the component.html, I am trying to iterate through the outer FormGroup's inner FormGroups, and print the inner FormControls. This is the code I have so far:
<form [formGroup]="sectionGroup">
<div *ngIf="boilerplate">
<div *ngFor="let section of boilerplate | keyvalue">
{{ boilerplate[section.key].desc }}
<div formGroupName="{{section.key}}">
<div *ngFor="let question of boilerplate[{{section.key}}]">
<-- things -->
</div>
</div>
</div>
</div>
The line <div *ngFor="let question of boilerplate[{{section.key}}]"> fails with an error message of:
Unexpected token {, expected identifier, keyword, or string
I have tried the following solutions, none of which have worked for me:
<div *ngFor="let question of {{boilerplate}}.{{section.key}}">
<div *ngFor="let question of {{boilerplate[section.key]}}">
<div *ngFor="let question of {{boilerplate[{{section.key}}]}}">
<td *ngFor="let question of Section">{{boilerplate[[section.key]]}}</td>
I have tried a variety of other {} and [] combinations and orders, and I realize now that nested interpolation is non-parsable.
Does anyone have a suggestion of how I can achieve this? I am using nested FormGroups because it is possible I will have additional layers of sections in the future. The format of the Boilerplate object can be changed if it would make the problem solvable (because I defined it, myself).
EDIT
The following was the solution that resolved this issue:
<div *ngFor="let question of boilerplate[section.key].content | keyvalue">
{{question.value}}
</div>
I try like below,
<div [formGroup]="formGroup">
<div *ngIf="boilerplate">
<div *ngFor="let section of boilerplate | keyvalue">
{{ boilerplate[section.key].desc }}
<div>
<div *ngFor="let question of boilerplate[section.key].content | keyvalue">
{{ question | json }}
</div>
</div>
</div>
Output is like below,
section1
{ "key": "1", "value": "question 1.a:" }
{ "key": "2", "value": "question 1.b:" }
{ "key": "3", "value": "question 1.c" }
section2
{ "key": "4", "value": "question 2.a:" }
{ "key": "5", "value": "question 2.b:" }
{ "key": "6", "value": "question 2.c" }
{ "key": "7", "value": "question 2.d" }
You need to use a keyValue filter pipe then you could just have the following syntax, this will let you use ngFor* to iterate though objects rather than arrays.
<div *ngFor="let question of boilerplate | keyValue">
{{ question.key }} - {{ question.value }}
</div>
You can then do the same for the nested objects inside until you have the correct data displayed. This is not supported in all versions of Angular, but definitely fine in 8.
Where you have Objects with the key as a number, I would look to manipulate that into an array which would help you keep this a little more simple. Allowing you to use traditional *ngFor
The answer from schoolcoder is great, I just would like to post another example for people in the future with the same problem.
I have an object Block that holds a list of Transactions and I want to show it on my page using two *ngFor's
Block model class:
export class Block {
hash: string;
previousBlockHash: string;
transactions: Transaction[]; <<<<<<<<<<<
merkleRoot: string;
tries: number;
timestamp: number;
}
Transaction model class
export class Transaction {
hash: string;
text: string;
senderHash: string;
signature: string;
timestamp: number;
}
How I show it on my page:
Blocks:
<div class="container">
<ul class="list-group">
<li class="list-group-item" *ngFor="let block of blocks | keyvalue">
Hash: {{blocks[block.key].hash}}<br>
Previous block hash: {{blocks[block.key].previousBlockHash}}<br>
Merkle root: {{blocks[block.key].merkleRoot}}<br>
Tries: {{blocks[block.key].tries}}<br>
Timestamp: {{blocks[block.key].timestamp}}<br>
Transactions in this block:
<ul class="list-group">
<li class="list-group-item" *ngFor="let transaction of blocks[block.key].transactions">
{{[block.key]}}<br>
Hash: {{transaction.hash}}<br>
Text: {{transaction.text}}<br>
SenderHash: {{transaction.senderHash}}<br>
Signature: {{transaction.signature}}<br>
Timestamp: {{transaction.timestamp}}
</li>
</ul>
</li>
</ul>
</div>

Angular orderBy object possible?

I have a JSON object representing calendar dates. These are added through a CMS and I'd like to be able to filter them based on date. My schema set-up has made this more difficult than I thought. Is it possible to orderBy the day value in this JSON object or is there a filter workaround?
Here is my JSON object:
{
"_id" : ObjectId("53f252537d343a9ad862866c"),
"year" : {
"December" : [],
"November" : [],
"October" : [],
"September" : [],
"August" : [],
"July" : [
{
"day" : "21",
"title" : "Event Title",
"summary" : "Event Summary",
"description" : "oEvent Description",
"_id" : ObjectId("53f252537d343a9ad862866d")
}
],
"June" : [],
"May" : [],
"April" : [],
"March" : [],
"February" : [],
"January" : []
},
"__v" : 0
}
Here is my view which already uses a custom filter to filter by month. The orderBy is not functioning but I've left it in as a placeholder to show where I'd like to set the functionality.
<div class="calDynamic" data-ng-repeat="n in [] | range:100">
<div ng-repeat="cal in calendar[n].year | filterKey:month">
<div ng-if="cal != '' ">
<div class="calendar">
<div ng-repeat="item in cal | orderBy: 'key.day' ">
<a href="/events/{{item.day}}">
<article class="eventslist">
<div class="numberedDate">
<h3>{{item.day}}</h3>
</div>
<div class="calInfo">
<h5>{{item.title}}</h5>
<p>{{item.summary}} <a>more</a></p>
</div>
</article>
</div><!-- ng-repeat val,key -->
</div><!-- calendar -->
</div><!-- ng-if cal -->
</div><!-- ng-repeat cal -->
</div><!-- calDynamic -->
You should be able to define a custom sort function that sorts by any item in your object. The key bit is to convert the object to an array in the filter function.
Here's an example:
app.filter('orderByDayNumber', function() {
return function(items, field, reverse) {
var filtered = [];
angular.forEach(items, function(item) {
filtered.push(item);
});
filtered.sort(function (a, b) {
return (a[field] > b[field] ? 1 : -1);
});
if(reverse) filtered.reverse();
return filtered;
};
});
You would then call it like this:
<div ng-repeat="(key, val) in cal | orderByDayNumber: 'day' ">
Note, you shouldn't write val.day as that is assumed.
Look at this great blog post here for more info.
EDIT: In fact, it looks like your structure is actually already an array, so while this technique will still work, it may not be necessary - it might have just been the way you were adding the parameter to orderBy that was causing issues.