I'm new to Angular 6 and i'm having trouble on how i can add objects into observable in a service.
i have this observable
getContacts(){
return this.contact =
this.http.get('https://jsonplaceholder.typicode.com/users');
}
and i need to add an item into that observable via another function
addContact(item){
//observable insertion goes here.
}
Here is my full service code
export class ContactService {
contact;
details;
constructor(private http: HttpClient) {}
getContacts(){
return this.contact =
this.http.get('https://jsonplaceholder.typicode.com/users');
}
addContact(contactName: string, contactPhone: string){
}
}
If this.contacts
is an Observable of list of objects (contacts: Observable<Items[]>
) and you want to make some changes to that list, you can simply use map
:
import { map } from 'rxjs/operators';
this.contacts.pipe(map(usersList => {
usersList.push(newItem);
return usersList;
}));
But if you want to make another request to the server and merge these lists, you can use forkJoin
:
import { forkJoin } from 'rxjs';
forkJoin(
this.contacts,
this.http.get('https://jsonplaceholder.typicode.com/other_users');
).pipe(
map(data => {
const [currentResult, pastResult] = data;
// ...
}
));
Update
Based on your comment for more details, you don't need to do anything with observables. What you need is something like this:
In your contacts.service.ts
:
getContacts(){
return this.http.get('https://jsonplaceholder.typicode.com/users');
}
In your contacts.component.ts`:
contacts: any[] = [];
ngOnInit() {
this.contactsService.getContacts().subscribe(data => {
this.contacts = data;
});
}
addContact(item) {
this.contacts.push(item);
}
But if you really want to have your contacts list as an Observable, you should use Subject
.
In your contacts.service.ts
:
$contactsChange = new Subject<any>();
private contactsList = [];
getContacts(){
return this.http.get('https://jsonplaceholder.typicode.com/users').pipe(map(data => {
this.contactsList = data;
this.$contactsChange.next(this.contactsList);
}));
}
addContact(item) {
this.contactsList.push(item);
this.$contactsChange.next(this.contactsList);
}
In your contacts.component.ts`:
contacts: any[] = [];
ngOnInit() {
this.contactsService.getContacts().subscribe(data => {this.contacts = data});
this.contactsService.$contactsChange.subscribe(data => {this.contacts = data});
}
The addContact () method is where you subscribe to the observable getContacts():
getContacts(): Observable<any> {
return this.contact =
this.http.get('https://jsonplaceholder.typicode.com/users');
}
At the time of subscription is when the call is triggered:
addContact(){
let cont: Observable<contactModel>;
cont = this.getContacts();
prueba.finally(() => {
console.log('Finally callback')
})
cont.subscribe(res => {
console.log('at the time of subscription is when the call is triggered')
let resp: contactModel[];
resp = res.json() as contactModel[];
});
}
Working With Observable
In Your Service
private contactInsertedSubject = new Subject<Contact>();
contactInsertedActions$ = this.contactInsertedSubject.asObservable();
public contacts$ = this.http.get<Contact[]>(this.contactsUrl)
.pipe(
// tap(data => console.log('Contacts: ', JSON.stringify(data))),
catchError(this.handleError)
);
public contactsWithAdd$ = merge(this.contacts$, this.contactInsertedActions$)
.pipe(
scan((acc: Product[], value: Product) => [...acc, value])
);
addContact(newContact?: Contact) {
this.contactInsertedSubject.next(newContact);
}
Your Contact Component Class
contacts$ = this.contactService.contactsWithAdd$;
onAdd(): void {
this.contactService.addProduct();
}
when this add method will call the subject in service will emit the value and merge observable has two input observable if any one will emit value so this will call automatically and then in pipe map operator will do the insertion job and contactWithAdd observable will have updated list.