How to use pipe on ionic 2 to make subcategories under parent categories

since on angular  we unable to use ngIf and ngFor on same element, like <div ngIF=”something” ngFor=”let blabla of data”>  this will return error. Angular2 doesn’t support more than one structural directive on the same element.

so if we want to have conditional on ngFor what we do? using pipes, pipes could be something like filter. we need to let ngFor know what they need to output and what they don’t need to output.

ok, here is out goal to achieve, we output the code from mysql it is categories and subcategories.

here is json data structure.

{“name”: “A”, “id”: 1, “parent_id”: 0},
{“name”: “B”, “id”: 2, “parent_id”: 0},
{“name”: “A1”, “id”: 3, “parent_id”: 1},
{“name”: “A2”, “id”: 4, “parent_id”: 1},
{“name”: “B1”, “id”: 5, “parent_id”: 2},
{“name”: “B2”, “id”: 6, “parent_id”: 2},

and we want angular to output like make subcategories to list under parent categories


Here is  home.ts code

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';

selector: 'page-home',
templateUrl: 'home.html'
export class HomePage {

category: Array<any>;

constructor(public navCtrl: NavController) {
this.category = [
{"name": "A", "id": 1, "parent_id": 0},
{"name": "B", "id": 2, "parent_id": 0},
{"name": "A1", "id": 3, "parent_id": 1},
{"name": "A2", "id": 4, "parent_id": 1},
{"name": "B1", "id": 5, "parent_id": 2},
{"name": "B2", "id": 6, "parent_id": 2},


here is home.html


<ion-content padding>
<ul *ngFor="let parent of category">



If you run ionic serve  now, you can see, will output all the json.

ok, we going to add pipes to our project

Create a Folder under scr call: pipes
Create a File Under pipes Folder call:  myPipes.ts

myPipes.ts code

import { Pipe, PipeTransform } from '@angular/core';
name: 'filterCategory'      //<-------- lowercase filterCategory we are going to using on html file
export class HelloWorld implements PipeTransform {
transform(value, args:string[]) : any {
//         ^-----value here is data to pass, and args is argument we pass

  let menu = [];
    value.forEach(s =>{
      if(s.parent_id == args){

      return menu;


go to src/app/app.module.ts to declare our HelloWorld class

import { NgModule, ErrorHandler } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { MyApp } from './app.component';

import { AboutPage } from '../pages/about/about';
import { ContactPage } from '../pages/contact/contact';
import { HomePage } from '../pages/home/home';
import { TabsPage } from '../pages/tabs/tabs';

import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';

import { HelloWorld} from '../pipes/myPipes';  // <---------------------add this line, import our myPipes.ts here

  declarations: [
    HelloWorld   // <---------------------add this line, to decleartion our class HelloWorld
  imports: [
  bootstrap: [IonicApp],
  entryComponents: [
  providers: [
    {provide: ErrorHandler, useClass: IonicErrorHandler}
export class AppModule {}

code above, you can see comment line call add this line, to declare class we only add two line code, one is import file and another line is declare class.  important!!!

go back to home.html, update code


<ion-content padding>
<ul *ngFor="let parent of category | filterCategory:0">
  <li *ngFor="let subcat of category |">

<ul *ngFor=”let parent of category | filterCategory:0″>

above code you can see  filterCategory this is pipes we create, and with a argument 0, filterCategory will pass data to pipes value , on pipes we loop through each of category, only output data with parent_id is 0.  so we getting parent category.

<li *ngFor=”let subcat of category |”>

above code after we get parent category, now using parent category id as argument, so pipes will output all the all subcategories parent_id match parent category id.

all done here, any question leave comment. 🙂



Leave a Reply

Your email address will not be published. Required fields are marked *