0

What I want to do is to show the first row in HTML (in below code) only on a condition using *ngIf. I've done the basic validation, but I have a hard time and can't find how I can do *ngIf accessing an object key directly (and not using an *ngFor before, on a different element). What I want to do is to show the row only when object.key === 'specific value'. I've tried options with "keys", "Object" but nothing seems to work. If you guys have any suggestion I would appreciate it.

my HTML

<ion-grid *ngIf="!isLoading && loadedBio.length > 0">
<ng-container *ngFor="let bio of loadedBio">
  <ng-container *ngIf="bio.category === '1'">
    <ion-row class="ion-padding">
      <ion-col>
        <ion-list class="no-last-border">
          <ion-item
            detail="false"
            *ngIf="bio.category === '1'">
            <ion-label
              [ngStyle]="{
                color:
                  bio.category === '1'
                    ? '#A34F83'
                    : 'var(--ion-color-secondary)'
              }"
              class="bioLabel"
              >{{bio.friendlyName}}</ion-label>
          </ion-item>
        </ion-list>
      </ion-col>
    </ion-row>
  </ng-container>
</ng-container>

my JS object I want to access the key from has the following format

loadedBio = [{key: value, key2: value}]

enter image description here

alex
  • 179
  • 2
  • 3
  • 18
  • 1
    I don't think the object is correct. Did you mean: ``{key: 'value', key2: 'value'}`` – Sachin Singh Jul 31 '20 at 11:44
  • 1
    you must get an error from angular something like you can iterator over an object. – micronyks Jul 31 '20 at 11:46
  • Hi Sachin! Thank you for your reply! What I receive from the database is an array of multiple objects, like this: [{…}, {…}, {…}, {…}, {…}, {…}, {…}] and each object has indeed {key: 'value', key2: 'value'} – alex Jul 31 '20 at 11:48
  • I don't get any error because to be honest I don't know how to actually iterate inside the *ngIf.. if I try to access *ngIf="loadedBio.key" it's not working – alex Jul 31 '20 at 11:51
  • 1
    Can you update your question - because, as Sachin point out, this is invalid syntax: `loadedBio = {[key: value, key2: value]}` – Muirik Jul 31 '20 at 12:32
  • 1
    wow, so sorry. I just realised now... I updated it – alex Jul 31 '20 at 12:33

2 Answers2

2

If you need to display each of the properties on your found object, then, in your component, you'd want to convert that found object to an array first - where each element in the array represents a property on the object, and then iterate over it to display each element:

const obj1 = {
  a: 'a title',
  b: 42,
  c: false
};

const arr1 = Object.values(obj1);

Put together that would look like this. First, in the component:

import { Component } from '@angular/core';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {

   loadedBio = [{'key': 1, 'key2': 2}, {'key': 3, 'key2': 4}];

   obj1 = {
     a: 'a title',
     b: 42,
     c: false
   };

  arr1 = Object.values(this.obj1);

  constructor() {

  }

}

And in the view:

<ion-header>
  <ion-navbar>
    <ion-title>Home</ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>
  <ng-container *ngIf="loadedBio">
    <ion-list *ngFor="let bio of loadedBio">
      <ng-container *ngIf="bio.key === 1">
         <ion-item>{{bio.key}}</ion-item>
      </ng-container>
    </ion-list>
  </ng-container>

  <ng-container *ngFor="let e of arr1">
    <ion-item>{{e}}</ion-item>
  </ng-container>

</ion-content>

This should give you an idea of how to handle your situation. Sounds like you want to transform the data in your component, and then iterate over it need be in your view.

Here is a link to the working StackBlitz:

Muirik
  • 6,049
  • 7
  • 58
  • 116
  • Hi! That's amazing, I've tried something like what you showed me, please see in here: https://stackblitz.com/edit/ionic-v4-6gbfvc?embed=1&file=src/app/app.component.html , but I get a problem, every item gets added in a new list, even row and not on the same list as I would like to – alex Jul 31 '20 at 12:48
  • I updated the above code to be ionic-angular specific. – Muirik Jul 31 '20 at 12:49
  • Thank you, but do you have any idea how to prevent repeating the list and to have all items in just one list? – alex Jul 31 '20 at 12:52
  • Do you mean what you're seeing in your view? I ask because I don't see anything in the view on your stackblitz. – Muirik Jul 31 '20 at 12:54
  • ok, sorry.. i've updated my answer based on your response, however based on it my ion-list repeats as well and not only the ion-item..what I want to achieve is to not repeat the list and have only one list with the ion-items in it – alex Jul 31 '20 at 12:59
  • I notice you have this check multiple times: ` *ngIf="bio.category === '1'">`. You only need that in the `ng-container`, not on the `ion-item` within the `ng-container`. – Muirik Jul 31 '20 at 12:59
  • On your example I see `bioOne` printing once in the view. Is that the goal? – Muirik Jul 31 '20 at 13:01
  • No, what I want to achieve is to print all the elements from my object in ion-item and to have only one list. I am sorry if I am not clear enough, I just started coding 4 months ago. I've attached a picture of my console, I get a new row -> col ->list for each ion-item. What I would like is to have only one row, col and one list where to have all the printed ion-items – alex Jul 31 '20 at 13:04
  • No worries. So to clarify, do you want to match to a certain property on an object, and then list each of the properties for that one object in the view? – Muirik Jul 31 '20 at 13:06
  • Yes, basically I want to show the entire row, list etc based on *ngIf= "loadedBio.key1 === '1' " and then in that only list to show another key values "loadedBio.key2" but to iterate and repeat just the ion-item not the entire structure – alex Jul 31 '20 at 13:11
  • Thank you very much, but then the obj1 I ve to create it manually ? – alex Jul 31 '20 at 13:53
  • I really appreciate your help, but I have the feeling that I've complicated this so much as i feel lost.. so using your first answer I achieved the desired outcome (I placed the HTML in your stackblitz but commented) but when the *ngIf is false the row, col and list before still remain on the HTML and basically when the *ngIf is false I want to hide them as well – alex Jul 31 '20 at 14:02
  • It might be helpful to re-work your question - or ask a new one - where you show exactly what your incoming data is, and exactly what you'd like your final HTML output to look like based on that data. – Muirik Jul 31 '20 at 14:11
  • Yes, you are right, I am doing it now. If you still think you would like to help I will post the link to the question in here if not, I understand completely and I really appreciate the time you spent. – alex Jul 31 '20 at 14:15
2

Best to filter your array in the controller, like this

this.filteredBio = this.loadedBio.filter(el=>el.category === 'overall')

and then simply use *ngFor on this filteredBio array. This will only have the objects whose category is 'overall'

Another solution is to implement a custom pipe Refer this

Chetan Bansal
  • 1,794
  • 14
  • 18