I have created two components(table and form) and I want data to be transferred from form to table upon editing. I have written the following code which is throwing the error. Please see to it.console.log(val) is showing the correct value. I want this to be pushed in the data array.I have added both the table component and service
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { Student } from '../student';
import { StudentService } from '../student.service';
@Component({
selector: 'app-table',
templateUrl: './table.component.html',
styleUrls: ['./table.component.css']
})
export class TableComponent implements OnInit {
data: Student[] = []
single!:Student;
constructor(public service:StudentService) { }
getUsers(){
this.service.getStudents().subscribe((data:any) => {
this.data=data;
});
}
deleteUsers(id:number){
this.data = this.service.delete(id,this.data);
}
update(id:number){
this.service.update(id,this.data);
this.service.currentData.subscribe((val) => {
console.log(val)
this.single = val;
//this.data.push(val)
});
this.data.push({
"English":this.single.English,
"Hindi":this.single.Hindi,
"Maths":this.single.Maths,
"Science":this.single.Science,
"SST":this.single.SST,
"first_name":this.single.first_name,
"last_name":this.single.last_name,
"id":id
});
}
ngOnInit(): void {
this.getUsers();
}
ngOnDestroy(){
if(this.service.getStudents().subscribe()){
this.service.getStudents().subscribe().unsubscribe();
}
}
}
Service file
import { Injectable } from '@angular/core';
import { Student } from './student';
import { HttpClient } from '@angular/common/http';
import { throwError } from 'rxjs/internal/observable/throwError';
import { EventEmitter } from 'stream';
import { Observable } from 'rxjs';
import { HttpErrorResponse } from '@angular/common/http';
import { catchError } from 'rxjs/operators';
import { Router } from '@angular/router';
import { BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class StudentService {
users: Student[] = [];
private data1 = new BehaviorSubject(this.getStudents())
currentData = this.data1.asObservable();
private url = '../../assets/MOCK_DATA.json'
constructor(private http: HttpClient, private router: Router) {
}
getStudents(): Observable<Student[]> {
return this.http.get<Student[]>(`${this.url}`);
}
delete(id: number, data: Student[]): Student[] {
data = data.filter(item => item.id !== id)
return data;
}
update(id: number, data: Student[]): Student[] {
data = data.filter(item => item.id != id)
this.router.navigate(['/form']);
return data
}
setData(data:any) {
this.data1.next(data);
}
}
CodePudding user response:
Well, as far as I can see, you are trying to push Students[] from StudenService.currentData to another Students[], is it intended or something went wrong?
If you want to add all values from StudentService.currentData then you can try change this.data.push(val)
to this.data.push(...val)
CodePudding user response:
The problem you are facing seems to be due to this line in the service
private data1 = new BehaviorSubject(this.getStudents())
The type of data1 is BehaviorSubject<Observable<Student[]>>
because of this line
this causes the type of currentData
to be Observable<Observable<Student[]>>
here:
currentData = this.data1.asObservable();
Then in your component when you do:
this.service.currentData.subscribe((val) => {
console.log(val)
this.single = val;
//this.data.push(val)
});
the type of val
is Observable<Student[]>
;
Presumably you are getting the error when you do the currently commented line this.data.push(val)
;
the solution would be to fix the type of the BehaviorSubject
in the service. Something like this should do:
private data1 = new BehaviorSubject<Student[]>([]);
...
getStudents(): Observable<Student[]> {
return this.http.get<Student[]>(`${this.url}`).pipe(
tap(data => this.data1.next(data))
);
}
in addition to the above, there is a second issue as pointed by Hephaestus901.
When you do this.data.push(val)
you are adding an array as an item of the student array in this.data
. something like: [st1, st2, [st3, st4]]
.
instead do this.data = this.data.concat(val)
or as per Hephaestus901's answer