выполнения одной операции в RxJS после нескольких элементов обрабатываются


Я относительно новичок в RxJs и не могу связать одну операцию после обработки нескольких элементов, испускаемых с помощью оператора switchMap.

Сценарий

: Используйте внутренние данные для создания массива объектов для выпадающего списка, а затем выполните цепочку из одной операции для установки выбранного значения выпадающего списка.

Вот нерабочий код, который помогает проиллюстрировать проблему.

this.sub = this.dataService.getUserData()
    .switchMap((data) => Observable.from(data)) // create new data stream from inner data set
    .map((data: any) => {
        return { value: data._id, viewValue: data.firstName + ' ' + data.lastName };
    }) // create data structure for drop down
    .subscribe( (data) => {
        this.userDropDown.push(data); // this operation needs to run once per item emitted, and is working
        this.patchFormData(); // <-- However, this only needs to run once
    },
    (error) => console.log("error", error)
    );

Я пробовал различные операторы, которые трансформируют проблему, но не могу решить ее полностью. а) получить новый массив объектов на основе исходных данных и Б) выполнить одну операцию после завершения.

Любая помощь очень ценится.

Спасибо,

  • S. Arora

-- UPDATE: рабочая окончательная версия здесь основана на ответе ниже с незначительным исправлением синтаксиса:

this.sub = this.dataService.getUserData()
    .map((data: any[]) => {
        return data.map((x: any) => {
            return { value: x._id, viewValue: x.firstName + ' ' + x.lastName };
        });
    })
    .subscribe((data: any) => {
        this.userDropDown = data;
        this.patchFormData();
    },
    (error) => console.log("error", error)
    );
1 2

1 ответ:

На самом деле, вам вообще не нужен .switchMap(). Вы просто создаете несколько эмиссий с помощью Observable.from(), что совершенно не нужно, если вы действительно не хотите обновить свои выпадающие значения по одному.

Что вы можете сделать, это просто вернуть массив, использовать .map() чтобы преобразовать массив, а затем назначить его в свой выпадающий список значений.

this.sub = this.dataService.getUserData()
//this map is a function of Observable
    .map((data: any[]) => {
        //this map is a function of array, not observable.
        //use this to transform the data
        return data.map(x => ({value: x._id, viewValue: x.firstName + ' ' + x.lastName}))
    })
    .subscribe((data) => {
            //assign your values to your dropdown list, and not pushing it one by one.
            this.userDropDown = data;
            this.patchFormData();
        },
        (error) => console.log("error", error)
    );
Теперь у вас есть только одно излучение в вашем наблюдаемом (которое является вызовом api), а затем в вашей функции .subscribe(), вашей this.userDropDown и this.patchFormData() оба будут работать только один раз.