0

I am attempting to build a new component which uses two material design components inside its template. The idea is I will have a new component that upon selecting an item from an md-select will add that item to an md-chip-list, then clear the select and allow you to add additional items to the md-chip-list.

The component should take an optionsList which is an array of objects like:

[{ viewValue: "Eve",value:"E" }, { viewValue: "Bob", value:"B" }, { viewValue: "Alice", value:"A" }]

The component and template look as follows.

import { Component, OnInit, Inject } from '@angular/core';
import { Input } from '@angular/core';


@Component({
    selector: 'chip-set-select',
    templateUrl: './ChipSetSelect.component.html',
    styleUrls: ['./ChipSetSelect.component.scss']
})

export class ChipSetSelectComponent implements OnInit {
    @Input() optionList: any[];//TODO can we use generic instead of any? Really we want all these arrays to be of the same type, but we don't know the type in advance.
    //optionList: any[];//TODO can we use generic instead of any? Really we want all these arrays to be of the same type, but we don't know the type in advance.
    @Input() selectedItems: any[];
    selectValue: any;

    // Use "constructor"s only for dependency injection
    constructor() { }

    // Here you want to handle anything with @Input()'s @Output()'s
    // Data retrieval / etc - this is when the Component is "ready" and wired up
    ngOnInit() {
        //this.optionList = ["Susan", "Bob", "Alice"];
        //this.optionList = [{ viewValue: "Susan",value:"S" }, { viewValue: "Bob", value:"B" }, { viewValue: "Alice", value:"A" }];
    }
}
{{optionList}}
<div *ngFor="let option of optionList">value: {{option.value}} viewValue: {{option.viewValue}}</div>
<md-select class="fullWidth" placeholder="Select Funder(s)" [(ngModel)]="selectValue">
  <md-option *ngFor="let option of optionList" [value]="option.value">
    {{option.viewValue}}
  </md-option>
</md-select>
{{selectValue}}
<md-chip-list><md-chip *ngFor="let item of selectedItems">{{item}}</md-chip></md-chip-list>

When I then use the component like:

<chip-set-select [optionList]="getOptionList()" [selectedItems]="getSelectedFunders()"></chip-set-select>

things end up hanging before the select list shows as populated. Possible problems with *ngFor or let declaration? No errors appear in the browser console.

Curiously if I remove the optionList attribute and remove the @input in the component and test the same array of objects initialized during ngOnInit of the component the select list gets populated as expected even though its the exact same array of objects.

Likewise if I use an array of strings to pass into [optionList] and modify the other code accordingly...everything works to populate the select options with the string values.

Any idea what is going wrong or why elements which work separately are causing problems when composed to create the final product?

1 Answer 1

1

I stumbled upon this question when I was trying to diagnose/fix very similar issue. In my case the browser was also freezing. This was a classic symptom of an infinite loop! One event causing other event to fire. I failed to find exactly where it was happening but following fix resolved it(similar to yours).

The functional calls seem to be the culprit and causing the loop. Replace functional calls with reference to an array/object. Use two separate lists/array to store options and selections. Ex. options[] for select options and chips[] to store selected options. Whenever an option is selected have a function (add?) called to add that item to chips[]. Once it's added chips[] will have one more chip and it will be reflected on UI.

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

1 Comment

I solved this in a similar way, but haven't reported back as I don't really understand what's causing the breakage yet. I too used an array that I initialize during ngOnInit. Wasn't able to track down the cause of the infinite loop in Angular. Not sure why the method call works for an array of string, but not for an array of objects. It seems very odd.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.