Angular 6 add items into Observable

2020-03-03 06:39发布

问题:

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){

}

}

回答1:

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});
}


回答2:

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[];  
    });


}


回答3:

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.