Search code examples
angularangular5angular-ngselect

basvandenberg/ng-select issue with simple string array


I'm using the following ng-select module and I am having issues using it with simple arrays.

https://github.com/basvandenberg/ng-select

The option format it expects is an array of objects:

{
   value: string;
   label: string;
}

But I don't have that option with the data being provided.

My object:

{
    name: "something",
    tags: ["option1","option2","option3"],
    tagPrimary: "",
    ...
}

In my Angular5 component template:

<ng-select
      placeholder="Select a primary option..."
      [(ngModel)]="obj.tagPrimary"
      [options]="obj.tags">
</ng-select>

Now when using this, the dropdown that is generate has the 3 options but doesn't display anything because it is looking for an object with a label key.

I tried to create a function that would format the data correctly.

function format(tags){
    arr=[];
    _.each(tags,function(tag){
        obj.push({label: tag, value: tag});
    }
    return obj;
}

<ng-select
          placeholder="Select a primary option..."
          [(ngModel)]="obj.tagPrimary"
          [options]="format(obj.tags)">
</ng-select>

Although it does render the dropdown correctly now, the items are un-selectable. When viewing the source the DOM inspector, it appears that the style attribute on each option will disappear/reappear (like it is re-initializing with the function being triggered over and over again.)

is the function created correctly?


Solution

  • Instead of assigning [options]="format(obj.tags)" directly in your template, which likely causes the method to trigger on each change detection cycle, you should assign the return value of format() method to another 'property' in your component and use that property in the template.

    Assuming you have your obj available in the ngOnInit() (otherwise you should make this assignment when your obj property is available with values within your component),

    In your component,

    optionsForSelect: { label: string; value: string; }[]; // specifying the type, not necessary though, a type of 'any[]' would be sufficient
    
    format(tags){
      arr=[];
      _.each(tags,function(tag){
          arr.push({label: tag, value: tag});
      }
      return arr;
    }
    
    ngOnInit() {
      //after you get 'obj' property
      this.optionsForSelect = this.format(this.obj.tags);
    }
    

    In your template,

    <ng-select
        placeholder="Select a primary option..."
        [(ngModel)]="obj.tagPrimary"
        [options]="optionsForSelect">
    </ng-select>