angularasync-pipeangular-akitaakita

Angular async pipe displays only the first element of array


I have an array of strings that i get as a value from an observable.

In the view I am trying to display the values with async pipe.

the template displays only the value of the last item and multiplies it in the number of recieved objects.

When I log the values to the console inside the subscribe method the results are displayed as they should be.

enter image description here

component.ts

hideCategories = true;
categories$:Observable<string[]> = this.categoriesQuery.selectAll();
destroy$: Subject<boolean> = new Subject<boolean>(); 

ngOnInit()
{
  this.categoriesQuery.selectedIsCategoriesLoaded$.pipe(
    filter(isLoaded => !isLoaded),
    switchMap((isLoaded) =>
    {
      return this.ticketService.fetchCategories()
    }),
    takeUntil(this.destroy$))
    .subscribe(console.log);
}

component.html

<ul *ngIf="!hideCategories && categories$ | async as categories" class="search-ul w-100" id="categories">
    <li *ngFor="let cat of categories" (click)="onSelectCategory(cat)" class="pointer" tabindex="0">{{cat}}</li>
</ul>

Not sure if it's related but I am using datorama akita for state managment.

----Edit----

this.categoriesQuery.selectAll()

Is derived from datorama akita QueryEntity Class.

service.ts

  fetchCategories()
  {
    return this.http.get<string[]>(environment.endpoints.tickets.getCategories).pipe(
      tap(categories =>
         this.categoriesStore.setCategories(categories, true)
      ));
  }

store.ts

@StoreConfig({ name: 'categories' })
export class CategoriesStore extends EntityStore<CategoriesState>{

    constructor()
    {
      super(createInitialState());
  }

  setCategories(categories: string[], isCategoriesLoaded: boolean)
  {
    this.set(categories);
    this.update(state =>
    ({
      ...state,
      isCategoriesLoaded
    }))
  }
}
export function createInitialState(): CategoriesState
{
  return {
    isCategoriesLoaded: false
  }
}

Solution

  • So it turns out that akita store management has to receive an Entity that has an Id field.

    I was getting an array of strings from my back end and i tried to set this array to the store.

    That didn't work since a string is not an object with an Id property. So what I have done is to generate in my client an object with a fake id for each string i get.

    Since these objects do not change and i don't need to update/delete them this solution is good enough for me..