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

#angular #typescript #rxjs-observables

Вопрос:

У меня есть myObservable$, который возвращает следующий массив:

 [
 { "firstProp": "A", "secondProp": "NA", "available": false },
 { "firstProp": "B", "secondProp": "NA", "available": true },
 { "firstProp": "C", "secondProp": "Old", "available": false },
 { "firstProp": "C", "secondProp": "New", "available": false }
]
 

Мне нужен способ создать новый массив, чтобы проверить наличие «firstProp» и «доступно» и вставить в новый массив следующую структуру:

 [
 { imgSrc: 'pathTo/myImages/file1.svg', badgeStyle: val?.available ? 'fas fa-exclamation-circle fa-lg' : 'fas fa-check-circle fa-lg', cardLabel: 'First Label'},
 { imgSrc: 'pathTo/myImages/file2.svg', badgeStyle: val?.available ? 'fas fa-exclamation-circle fa-lg' : 'fas fa-check-circle fa-lg', cardLabel: 'Second Label'},
 { imgSrc: 'pathTo/myImages/file3.svg', badgeStyle: val?.available ? 'fas fa-exclamation-circle fa-lg' : 'fas fa-check-circle fa-lg', cardLabel: 'Third Label'},
]
 
Это мое решение, но я чувствую, что может быть лучшее решение для того, что я сделал:
 const OBJ1 = { imgSrc: 'pathTo/myImages/file1.svg', badgeStyle: val?.available ? 'fas fa-exclamation-circle fa-lg' : 'fas fa-check-circle fa-lg', cardLabel: 'First Label'};

const OBJ2 = { imgSrc: 'pathTo/myImages/file2.svg', badgeStyle: val?.available ? 'fas fa-exclamation-circle fa-lg' : 'fas fa-check-circle fa-lg', cardLabel: 'Second Label'};

const OBJ3 = { imgSrc: 'pathTo/myImages/file3.svg', badgeStyle: val?.available ? 'fas fa-exclamation-circle fa-lg' : 'fas fa-check-circle fa-lg', cardLabel: 'Third Label'};



myObservable$.subscribe((value) => {
      value?.forEach((val) => {
        if (val?.firstProp === 'A') {
          this.myNewArray.push(OBJ1);
        } else if (val?.firstProp === 'B') {
          this.myNewArray.push(OBJ2);
        } else if (val?.firstProp === 'C' amp;amp; val?.secondProp === 'New') {
          this.myNewArray.push(OBJ3);
        }
      });
    });
 
Я также не могу найти решение для случая, когда:

потому что я получаю 2 раза «firstProp» как » C «с разными типами «secondProp» (старый и новый). Правило состоит в том, что я должен отображать badgeStyle как «восклицание», когда либо один, либо оба «C» имеют «доступно»: true, и отображать «зеленую галочку» для badgeStyle, когда оба C имеют «доступно»: false

Комментарии:

1. вы могли бы сделать свой новый массив Observable также, а затем просто pipe без необходимости subscribe .

2. Как работает это условие? badgeStyle: val?.available ? 'fas fa-exclamation-circle fa-lg' : 'fas fa-check-circle fa-lg', У вас нет val свойства в объекте, которое он всегда будет возвращать false

3. Да, @Yuriy У меня есть вал.доступная недвижимость. Он исходит из массива, возвращаемого объектом myObservable со значением? .Предисловие

Ответ №1:

Допустим , вы изменили определение myNewArray свойства на an Observable , преимущества этого по сравнению с решением, которое вы используете в настоящее время, заключаются в том, что вам не придется беспокоиться о том, чтобы отказаться от подписки Observable , потому что angular позаботится об этой части за вас. Давайте продемонстрируем это ниже…

 //...

// so let us start by redefining the myNewArray as the Observable
myNewArray$: Observable<Array<{ imgSrc: string; badgeStyle: string; cardLabel: string }>>;

// you will need to initialize the above ofcourse so we will do this in the
// component constructor
constructor() {
  //... so then you initialize the myObservable property
  // then you assign the myNewArray
  this.myNewArray$ = this.myObservable$.pipe(
    map((value) => {
      if (val?.firstProp === 'A') {
        return OBJ1;
      } else if (val?.firstProp === 'B') {
        return OBJ2;
      } else if (val?.firstProp === 'C' amp;amp; val?.secondProp === 'New') {
        return OBJ3;
      }
      // you will probably get a ts error for not having an else statement
      // so you will need to accommodate the else state
    })
  );
}

//...
 

Исходя из вышесказанного, вы затем будете использовать async канал в своем html разделе кода компонентов.

 <ng-container *ngIf="(myNewArray$ | async) as newdata">
  <!-- content here -->
</ng-container>
 

Следовательно, у вас меньше утечек памяти, потому что angular отпишется от вас, когда
компонент будет уничтожен.

Комментарии:

1. Я бы не стал сейчас пытаться улучшить часть с утечкой памяти… Меня интересует лучшее решение для построения myNewArray, чем то, которое я сделал с множеством условий IF ELSE. Это моя главная цель. Как бы вы это сделали?