I have to transform an object property in a RXJS Observable. This works using the "map" operator. The problem occurs when I subscribe twice to the same observable: the property is transformed twice
I have tried to use the "share" operator and multiple variations but nothing seems to work
const source = of(
{ id: 1, name: 'John' },
);
const personObservable = source.pipe(
map(person => {
person.name = person.name + '_test'; return person;
}),
);
personObservable.subscribe(
person => console.log('first: ', person)
);
personObservable.subscribe(
person => console.log('second: ', person)
);
first: John_test
second: John_test
first: John_test
second: John_test_test
It is because you are modifying same object instance twice. When your map would return a copy of that object it would not happen. Try this:
const personObservable = source.pipe(
map(person => ({
...person,
name: person.name + '_test'
})),
);
You could also use shareReplay
operator with your original mapping function:
const personObservable = source.pipe(
map(person => {
person.name = person.name + '_test'; return person;
}),
shareReplay()
);
Another solution is to use Observable.create
or new Observable()
to create your Observable.
of
creates a multicast Observable. new Observable
will result in the creation of a cold, unicast Observable, which emits a new instance of your object for each Observer.
const source = new Observable((subscriber) => {
subscriber.next({ id: 1, name: 'John' });
subscriber.complete();
});
const personObservable = source.pipe(
map(person => {
person.name = person.name + '_test'; return person;
}),
);
personObservable.subscribe(
person => console.log('first: ', person)
);
personObservable.subscribe(
person => console.log('second: ', person)
);
Working StackBlitz:
https://stackblitz.com/edit/angular-bdhjuo
I also recently wrote an article explaining hot and cold Observables, which you may find useful:
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.