I am in quite a pickle and it could be the approach that I have been taking with learning about rxJS and Observables.
Preface
Our application uses Angular to connect to our public API layer (C#). The type of object that is returned from my ASYNC call is of Observable< ListResultDtoOfNoteDto > . This stream is passed to a child component which loops through the items. This same stream also allows a user to add new note of type NoteDto or edit notes. Ideally when these actions are done the list of notes will reflect the updated change without having to call the same service call for getting the notes again.
Code
[notes.component.html]
<div *ngIf="(notes$ | async)?.items as notes; else loading">
<note-card [noteData]="notes" (noteClick)="editNote($event)"></note-card>
</div>
<ng-template #loading>
<div class="notes__container">
<div class="note-card">
<div class="note-card__primary-action">
<div class="note-card__head">
<h2 class="note-card__title note-card-typography--headline1 text-center">Loading...</h2>
</div>
</div>
</div>
</div>
</ng-template>
[notes.component.ts]
import ...
@Component({
...
})
export class NotesComponent extends AppComponentBase implements OnInit {
constructor(
...
private _noteService: NoteServiceServiceProxy
) {
super(injector);
}
public notes$: Observable<ListResultDtoOfNoteDto>;
public userId: number;
...
ngOnInit() {
...
this.getNotes();
...
}
getNotes(): void {
/*
Binding to ASYNC pipe; which doesn't need a subscription since it is automatic?
Returns type: Observable<ListResultDtoOfNoteDto> which is an array of NoteDto
*/
this.notes$ = this._noteService.getUserNotes(this.userId, null);
...
}
...
public saveNote(note: NoteDto, mode: string) {
if (mode === 'new') {
this._noteService.addNote(note).subscribe(() => {
this.cleanUp();
this.getNotes();
this.notify.info(this.l('SavedNoteSuccessfully'));
});
}
...
}
}
All of the functionality minus the clickEvent in the child happens within the parent. Which loads a form (reactive form methodology) that can take a new note and save or edit an older note to update.
My issue
I am just wanting a way to save the note and update the list without having to call this.getNotes() again in the subscription when a new note is added.
(I can provide more details if needed!)
EDIT: Forgot to show save method currently
One way in which you can achieve this is to have a private BehaviorSubject inside of your NoteServiceServiceProxy
which will always contain the latest value of notes.
Like: private _notes = new BehaviorSubject<ListResultDtoOfNoteDto>(null)
public getNotes(): Observable<ListResultDtoOfNoteDto> {
return this._notes.asObservable();
}
public getNotesFromApi(args): {
// Api request
this.httpClient.get().pipe(tap(result) => this._notes.next(result))
// etc...
}
Then all you need to do in your component is declare your observable something like
notesData = this. _noteService.getNotes();
inside init
just make request to API to get the notes and it will automatically update your notesData
which should be subscribe on your template via async
pipe output.
When you save all you need to do is just add a concatMap
at the end so that your save goes first then you request the update from your api.
So something like
this._noteService.addNote(note).pipe(
concatMap(() => this._noteService.getNotesFromApi()))
.subscribe();
This again will update your notesData variable which is on the template.
I hope you understand how this flow works and if not feel free to ask.
Hope this helps!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.