Я пытаюсь иметь наблюдаемое, основанное на субъекте, чтобы оно обновлялось каждый раз, когда SUbject излучает.
По какой-то причине при попытке получить значение наблюдаемого первое значение всегда равно нулю, а остальные содержат значения. Я ожидаю получить последнее испущенное значение наблюдаемого. Я пробовал со всеми типами предметов. Что мне не хватает?
...
activeBookings$: Subject<Booking[]> = new BehaviorSubject<Booking[]>(null);
activeBooking$: Observable<Booking> = this.activeBookings$.pipe(
filter((bookings) => bookings?.length > 0),
mergeMap((bookings) => this.getBookingById(bookings?.[0]?.id)),
share()
);
i = 0;
constructor(
public http: HttpClient,
public store: Store,
public asyncPipe: AsyncPipe,
public bookingStoreService: BookingStoreService
) {
this.getBookings().subscribe((bookings) => {
this.bookings$.next(bookings);
});
this.getActiveBookings().subscribe((bookings) => {
this.activeBookings$.next(bookings);
});
this.getPreviousBookings().subscribe((bookings) => {
this.previousBookings$.next(bookings);
});
}
...
Вот где я пытаюсь получить последнее значение:
...
const booking: Booking = this.asyncPipe.transform(
this.bookingService.activeBooking$
);
booking.status = status; //error: booking is null
...
Но я, например, использовал ReplaySubject, и у меня есть фильтр для игнорирования нулей. Это не должно быть причиной
Здесь вы используете BehaviorSubject с начальным значением null:
activeBookings$: Subject<Booking[]> = new BehaviorSubject<Booking[]>(null);
Вместо этого вы можете инициализировать его пустым массивом, например:
activeBookings$: Subject<Booking[]> = new BehaviorSubject<Booking[]>([]);
Это было бы более последовательным типом, иначе ваш реальный тип:
activeBookings$: Subject<Booking[] | null> = new BehaviorSubject<Booking[] | null>(null);
Почему вы получаете ноль? BehaviorSubject должен быть инициализирован значением, и, вероятно, поэтому первое значение, которое вы получаете, равно нулю. Простой Subject не обязательно должен содержать начальное значение, и вы, вероятно, не получите null
activeBookings$: Subject<Booking[]> = new Subject<Booking[]>()
Более понятным способом получения последнего значения без подписки на другую службу было бы использование функций BehaviorSubject и того факта, что вызов activeBooking$.value позволяет получить последнее значение BehaviorSubject. Преобразуйте свое поле activeBooking$ так, чтобы оно было BehaviorSubject, и при подписке на результат getActiveBookings() вы могли бы выполнить вычисления, которые в настоящее время находятся в канале определения activeBooking$, и вызвать next на activeBooking$ с результатом и выставить геттер для вашего другого сервиса:
get activeBooking(): Booking {
return this.activeBooking$.value
}
Отличный ответ. О последнем предложении. В нем говорится, что «значение» не является свойством субъекта. Ни .getValue(), который я также пробовал с BehavorialSubject. Должно ли это работать?
activeBooking$ необходимо указывать как BehaviorSubject: activeBooking$: BehaviorSubject<Booking>, а не как Subject
Правильно, моя вина. Это работает по назначению, спасибо. Это решение, которое я искал, но я не буду тратить на него больше времени. Я буду вести активную регистрацию в качестве Субъекта, а не наблюдаемого
Вы используете
new BehaviorSubject(null)
, так вот откудаnull