2

I am binding data in model class and looping the data fine. But I failed to bind toggle function in model class to the template click event.

I created a model to bind the data from a jokelist component and looping the jokes with ngFor directive. Created jokerow component and send joke object as input param from jokelist. the properties are working fine. but the function is not detected.

Model:

export interface IJoke {
    fname: string;
    lname: string;
    hide: boolean;    
}

export interface IJokelist {
    jokeList: IJoke[];
}

export class JokeModel {
    jokeList: IJokelist;
    joke: IJoke;
    hide: boolean;

    constructor(jokeList: IJokelist) {
        this.jokeList = jokeList;
        // this.hide = true;
    }

    getAllProducts(): any {
        return this.jokeList;
    }

    toggle(): void {
        //this.hide = !this.hide;
        console.log('hi');
    }
}

jokelist.Component.ts

export class JokelistComponent implements OnInit {

  jokesList: IJokelist;

  jokesStatic: any = [{ fname: 'chandu', lname: 'm', hide: true },
  { fname: 'venkat', lname: 'p', hide: true },
  { fname: 'ramu', lname: 'b', hide: true }];


  constructor() {
    const newProduct = new JokeModel(this.jokesStatic);
    this.jokesList = newProduct.getAllProducts();
  }

  ngOnInit() {
  }
}

jokelist.component.html

<app-jokerow *ngFor="let j of jokesList" [joke]="j"></app-jokerow>

jokerow component

export class JokerowComponent implements OnInit {
  @Input('joke') data: IJoke;

  constructor() { }

  ngOnInit() {
  }

}

jokerow.component.html

<div class="card card-block">
    <h4 class="card-title">{{data.fname}}</h4>     
    <p class="card-text"
     [hidden]="data.hide">{{data.lname}}</p>
  <a (click)="data.toggle()"
     class="btn btn-warning">Tell Me
  </a>
</div>
chandoo
  • 1,276
  • 2
  • 21
  • 32

2 Answers2

1

toggle function is not specific to your model.

You have to pass data to toggle and then you can show/hide.

<a (click)="toggle(data)"
     class="btn btn-warning">Tell Me
  </a>

In component,

 toggle(data): void {
        data.hide = !data.hide;   //updated
        console.log('hi');
    }

Hope this helps.

Dheeraj Kumar
  • 3,917
  • 8
  • 43
  • 80
  • hi is showing in the console. but, the display toggle is not showing the data. – chandoo Jul 23 '18 at 12:21
  • I updated answer. it should be !data.hide instead of !this.hide – Dheeraj Kumar Jul 23 '18 at 12:22
  • Tq, its done, but can you tell me why angular did not detect the same function in written in model. – chandoo Jul 23 '18 at 12:24
  • toggle function isn't part of your model, yur model has just 3 properties, no function. – Dheeraj Kumar Jul 23 '18 at 12:25
  • JokeModel has toggle function right? and the IJokelist is injected in constructor. You solved my issue but can you help me to understand it why? – chandoo Jul 23 '18 at 12:29
  • 1
    JokeModel is a normal class with toggle function which is called by IJoke(data) model from view, but that function is not part of IJOke. that is why you can't directly call toggle function. If you want to directly call toggle, you have to include it in IJoke interface. – Dheeraj Kumar Jul 23 '18 at 12:52
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/176641/discussion-between-chandoo-and-dheeraj-kumar). – chandoo Jul 24 '18 at 11:56
0

Update getAllProducts so jokesList elements will have toggle function

getAllProducts(): any {
    return this.jokeList.map (j => { 
        j.toggle = this.toggle;
        return j;
    });
}
Muhammed Albarmavi
  • 23,240
  • 8
  • 66
  • 91