How to push object into an object array in Angular 6? - javascript

I have an empty object array like this groupList:any = {} and now I want to push an object into it. I am trying to name and description as an object.

It is not an array, array is represented like [] , probably you need
groupList:any = [];
and then,
this.groupList.push({name:'you',description:'what is array'});

app.component.ts
declare var require: any;
import { Component } from '#angular/core';
import { OnInit } from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent{
groupList:any = [];
arrayVal:any;
currentVal : any;
title = 'projectchart';
public array = [{"id":1},{"id":3},{"id":5}];
getPrev(){
this.array.forEach((item, index) => {
this.groupList.push(item.id);
});
console.log(this.groupList);
}
}
app.component.html
<button (click) ="getVal()">Previous Value</button>

Related

Angular: How can i push an observable to a list

I get an Error message that i cant push an undefined variable to my list.
This is my code in the component.ts
for (const file of this.allFiles) {
this.uploadFileService
.validate(file)
.subscribe( valid => {
this.validList.push(valid);
})
}
This is my Service:
validate(file: File): Observable<boolean> {
const data: FormData = new FormData();
data.append('file', file);
return this.http.post<boolean>(`${this.url}/validate`,data);
}
How can I push to the list?
You will get this error if you do not initialize the array ([]) first before pushing. Please declare the variable validList: Array<any> = [] at the top of the component before pushing data inside.
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit{
name = 'Angular';
validList: Array<any> = [];
ngOnInit() {
this.validList.push(true);
}
}
Issue replicated stackblitz
Working stackblitz

execute a function evertime ngFor is finished displaying data

I am trying to call a function everytime my ngFor is done loading data from my API.
but the callback is only triggering on first load of the ngFor.
how can I execute the callback everytime my ngFor is changed;
I used this answer: https://stackoverflow.com/a/38214091/6647448
here is what I have so far...
HTML
<button class="btn" (click)="changeDate()"></button>
<div *ngFor="item of items; let last = last">
<div>{{item}}{{last ? ngForAfterInit() : ''}}</div>
</div>
TS
this.ngForIsFinished = true;
ngForAfterInit() {
if (this.ngForIsFinished) {
this.ngForIsFinished = false;
}
}
changeDate() {
// this is where i trigger my ngFor to change its content
}
The person who answered said that you just need to set the ngForIsFinished back to true but I am having a hard time where to set it on my code.
Try to use ChangeDetectionStrategy.OnPush and last variable of ngFor. Because ChangeDetectionStrategy.Default always checks methods, so fooMethod(...) will be called multiple items:
<div *ngFor = "let title of iterated; let i=index; let last=last">
{{last ? fooMethod(last) : '' }}
</div>
yourComponent.ts:
import { Component, ChangeDetectionStrategy } from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class AppComponent {
name = 'Angular 4';
iteratedData = [
{"title":"test1","description":"foo","name":"name1"},
{"title":"test2","description":"foo","name":"name2"},
{"title":"test3","description":"foo","name":"name3"},
{"title":"test4","description":"foo","name":"name4"}
];
fooMethod(v) {
if (v)
console.log(`This is from the method ${v}`);
}
}
UPDATE:
After you've loaded data you should call slice method as Angular 2 change detection strategy doesn't check the contents of arrays or object. So try to create a copy of the array after mutation:
this.iteratedData.push(newItem);
this.iteratedData = this.iteratedData.slice();
OR:
constructor(private changeDetectorRef: ChangeDetectorRef)
And you can call a method markForCheck to trigger a changeDetection:
this.iteratedData.push(newItem);
this.changeDetectorRef.markForCheck();
Here is the example:
Component:
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular 5';
data:any = [];
ngAfterViewInit(){
this.changeDate();
}
ngForAfterInit(valuue) {
alert('FOR LOOP COMPLETED : '+ valuue);
}
ChangeDate(){
let i = 0;
setInterval(()=>{
this.data=[];
for(var j=0; j<10; j++){
this.data.push("TEST DATA "+ j+" SET AT : "+i);
};
i+=1;
},7000);
}
}
html:
<div *ngFor="let item of data; let last=last;">
{{item}} {{last? ngForAfterInit(item) :''}}
</div>
SetInterval is like your API which will assign data.This is working for me
https://stackblitz.com/edit/pokemon-app-4n2shk

Angular-6: Convert string to array of a custom object

I have this produced string:
string str = [{"id":1,"name":"Angular"},{"id":2,"name":"SpringBoot"}]
I'd like to convert it to an array of Objects to have that:
listexps: Expertise[];
listexps = [{"id":1,"name":"Angular"},{"id":2,"name":"SpringBoot"}];
And Expertise class is
export class Expertise
{
id: number;
name: string;
}
I tried that:
let array = str .replace('[{','').replace('}]','').split("},{").map(String);
but that didn't resolve my problem, I got:
"id":1,"name":"Angular","id":2,"name":"SpringBoot"
instead of
[{"id":1,"name":"Angular"},{"id":2,"name":"SpringBoot"}];
Have you please any idea about solving that ?.
Big thanks.
What you need is JSON.parse; it converts string to an object;
relevant ts:
import { Component } from '#angular/core';
export class Expertise {
id: number;
name: string;
}
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
name = 'Angular';
strIntoObj: Expertise[];
constructor() {
let str: string = '[{"id":1,"name":"Angular"},{"id":2,"name":"SpringBoot"}]';
this.strIntoObj = JSON.parse(str);
console.log(this.strIntoObj);
}
}
complete working stackblitz here

Why Angular 2+ innerHTML is calling method multiple times in a single statement, How to solve this

I have the template view like this.
<p [innerHTML]="myfunction()"></p>
and, ts file be like
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular';
myfunction(){
alert(name);
return '<div>abcd</div>';
}
}
Its a simple method calling from html to render the html content through innerhtml, here the myfunction() is calling multiple times, and i'm getting multiple alerts, can anyone help me to solve this.
the stackblitz for this is link
thanks in advance
You can use pure pipe to only rerun it if inputs to the pipe have changed:
#Pipe({name: 'functionCaller'})
export class FunctionCallerPipe {
transform(func: any, ...args: any[]): any {
return func(...args);
}
}
And use it like that:
<p [innerHTML]="myfunction| functionCaller : name"></p>
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular';
myfunction(name: string){
alert(name);
return '<div>' + name + '</div>';
}
}

How to render a list retrieved from firebase

I want to render a list in angular project with data retrieved from firebase, but I cannot render it to my list.
I tried on Angular 7
//this is my ts code
import { Component } from '#angular/core';
import { AngularFireDatabase } from '#angular/fire/database';
import { PassThrough } from 'stream';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
courses: any[];
constructor(db: AngularFireDatabase) {
db.list('/courses').snapshotChanges().subscribe(courses =>{
this.courses = courses;
console.log(this.courses);
});
}
}
//this is the html
<ul>
<li *ngFor="let course of courses">
{{course.value}}
</li>
</ul>
I want it to show like this
course1
course2
but the list are rendered with only a dot like this
-
inside subscribe() this does not reference to courses you need to assign this to another variable like let self=this;
Try the following code i hope this will work for you
import { Component } from '#angular/core';
import { AngularFireDatabase } from '#angular/fire/database';
import { PassThrough } from 'stream';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
courses: any[];
constructor(db: AngularFireDatabase) {
let self=this;
db.list('/courses').snapshotChanges().subscribe(courses =>{
self.courses = courses;
console.log(courses);
});
}
}
Small issue, you cannot assign the node to this.courses
export class AppComponent {
courses: any[];
constructor(db: AngularFireDatabase) {
db.list('/courses').snapshotChanges().pipe(
map(changes =>
changes.map(c => ({ key: c.payload.key, ...c.payload.val() }))
)
).subscribe(courses =>{
this.courses = courses;
console.log(this.courses);
});
}
}
ref: https://github.com/angular/angularfire2/blob/master/docs/rtdb/lists.md
Also, make sure that course.value, "value" property exists in course object.
<ul>
<li *ngFor="let course of courses">
{{course.value}} <-- here ??
</li>
</ul>

Categories

Resources