0

I'm trying to pass the index from a ngFor to a my ts file without any success. I actually don't know how to do that. Can someone tell me how to pass the index value from the html to the ts file? I thought using a @Input would be te solution but nothing happen... Thanks.

My HTML:

<div *ngFor="let question of questions | async; index as i">{{question.libelle}}
     <div class="row text-left options">
        <div class="col-md-6" *ngFor="let reponse of reponses | async">
          <div class="option">
            <label class="" [attr.for]="reponse.id">
                <input type="checkbox" [(ngModel)]="reponse.Selected"/>
                {{reponse.libelle}}
            </label>
          </div>
        </div>
      </div>
      {{i}}
    </div>

My TS:

@Injectable()


@Component({
  selector: 'app-java',
  templateUrl: './java.component.html',
  styleUrls: ['./java.component.sass']
})
export class JavaComponent implements OnInit {
  @Input()  i : any;
  questions :any = [];
  reponses :any = [];
  constructor(private questionnaireService: QuestionnaireService) { }

  ngOnInit() {
    this.questions = this.questionnaireService.getQuestion();
    this.reponses = this.questionnaireService.getReponse(this.i);
  }  

}
1
  • is the html you have there the template code for the app-java component? index is a variable local to the ngFor loop. it is not available or set in the component controller. Commented Oct 18, 2018 at 16:41

3 Answers 3

1

you seem to have a basic misunderstanding of the index variable context and how observables will work. What could help here and clear things up is dividing your component into two components, one for managing and displaying the overall list and one for managing and displaying the child lists

The parent (app-java):

HTML:

<div *ngFor="let question of questions | async; index as i">{{question.libelle}}
 <div class="row text-left options">
    <app-java-child [i]="i"></app-java-child>
  </div>
  {{i}}
</div>

TS:

@Component({
  selector: 'app-java',
  templateUrl: './java.component.html',
  styleUrls: ['./java.component.sass']
})
export class JavaComponent implements OnInit {
  questions :any = [];
  constructor(private questionnaireService: QuestionnaireService) { }

  ngOnInit() {
    this.questions = this.questionnaireService.getQuestion();
  }  

}

and the child:

HTML:

<div class="col-md-6" *ngFor="let reponse of reponses | async">
   <div class="option">
     <label class="" [attr.for]="reponse.id">
            <input type="checkbox" [(ngModel)]="reponse.Selected"/>
            {{reponse.libelle}}
     </label>
   </div>
</div>

TS:

@Component({
  selector: 'app-java-child',
  templateUrl: './java-child.component.html',
  styleUrls: ['./java-child.component.sass']
})
export class JavaChildComponent implements OnInit {
  @Input()  i : any;
  reponses :any = [];
  constructor(private questionnaireService: QuestionnaireService) { }

  ngOnInit() {
    this.reponses = this.questionnaireService.getReponse(this.i);
  }  

}

This way you take the index from the initial ngFor and feed it to the child as input so the children can be in charge of building their own response arrays.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the answer. I copy and paste your code but the child doesn't appear. Do you have an idea why ? The ide doesn't show any error...
Actually, it works like a charm. You are the Man. Thanks !!
0

You can achieve these with 3 steps

  1. Keep the currentIndex in ts file

  2. Set the currentIndex from the html

  3. Call getter method from the *ngFor

in ts

@Injectable()
@Component({
  selector: 'app-java',
  templateUrl: './java.component.html',
  styleUrls: ['./java.component.sass']
})
export class JavaComponent implements OnInit {
  @Input()  i : any;
  questions :any = [];
  reponses :any = [];
  constructor(private questionnaireService: QuestionnaireService) { }

  ngOnInit() {
    this.questions = this.questionnaireService.getQuestion();
  }  

   //Track the current Index
   public currentIndex;

   //Current Index Setter
   setCurrentIndex(index){
       this.currentIndex = index;
   }

  //Getter for response which will use currentIndex
  get responses(){
    return this.questionnaireService.getReponses(this.currentIndex)
  }

}

in html

   <div *ngFor="let question of questions | async; index as i">{{question.libelle}}
         <div class="row text-left options" #>

            {{setCurrentIndex(i)}} <-- Set the current Index -->

            <div class="col-md-6" *ngFor="let reponse of responses | async">
              <div class="option">
                <label class="" [attr.for]="reponse.id">
                    <input type="checkbox" [(ngModel)]="reponse.Selected"/>
                    {{reponse.libelle}}
                </label>
              </div>
            </div>
          </div>
          {{i}}
 </div>

Note : since you are using async pipe make sure all your results are Observable.

4 Comments

It tells me that getReponses is unknown... What m'i doing wrong?
I just tried it too, as never seen this type of syntax, gives index undefined and the function never called. Can you please elaborate, how this syntax will work or any reference to understand the syntax used...
Check if you have function getReponses in your ts file.
Updated the answer with alternative solution.
0

normally <div *ngFor="... let ii==index"> will be enough to pass the ii, however, in my case there is a *ngIf in sub , so that messed up the count and made it undefined. I endup make the *ngIf on the top level above *ngFor.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.