Malik Kashmiri Malik Kashmiri - 2 months ago 53
TypeScript Question

ng2-select not working when I get data from api and cast it in initData

Detail



I use ng2-select in the form. I retrieve data from api and set into the array but it not working correctly. bellow is my code. when I hard code it is working fine. I have no clue why this is doing this, may be because It initialize the array with empty data after that the response get the data but not set it to the array.

import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import {Observable} from 'rxjs/Observable';
import { AuthService } from '../../services/auth/auth.service';
import {SELECT_DIRECTIVES} from 'ng2-select';

@Component({
selector: 'users-edit',
templateUrl: '../../app/components/user/user-edit.html',
directives: [SELECT_DIRECTIVES]
})
export class UserEditComponent implements OnInit{
private isAdmin: Boolean = false;
private _data: Observable;
private fname: string;
private id: number;
private lname: string;
private email: string;
private _roles: Observable;
public roles: any = [];
public groups: any = ['Group 1', 'Group 2', 'Group 3', 'Group 4', 'Group 5'];
private initRoleData: Array[]=[];
private _disabledV: string = '0';
private disabled: boolean = false;


constructor(private router: Router,
private userService: UserService,
private route: ActivatedRoute,
private authService: AuthService) {

this.route.params.subscribe(params => {
this.id = +params['id'];
});
}

ngOnInit() {
this.userService.getUser(this.id)
.subscribe(data => {
this.fname = data.FirstName;
this.lname = data.LastName;
this.email = data.Email;
});
this.userService.getUserRolesById(this.id)
.subscribe(data => {
data.forEach(role => {
this.initRoleData.push(role.Name);
});
});
console.log(this.initRoleData);
this.userService.getAllRoles()
.subscribe(data => {
data.forEach(role => {
this.roles.push(role.Name);
});
});
console.log(this.roles);
}
}


html





<div class="row margin-bottom-40" style="margin-top:50px;">
<div class="col-md-12">
<!-- Reg-Form -->
<form id="sky-form4" class="sky-form" (ngSubmit)="Submit(userEdit)" #userEdit="ngForm">
<header>Edit User Account</header>

<fieldset>
<section>
<label class="input">
<i class="icon-append fa fa-user"></i>
<input type="text" name="username" placeholder="First Name" required [value]="fname">
<b class="tooltip tooltip-bottom-right">Enter First Name</b>
</label>
</section>

<section>
<label class="input">
<i class="icon-append fa fa-user"></i>
<input type="text" name="username" placeholder="Last Name" [value]="lname">
<b class="tooltip tooltip-bottom-right">Enter Last Name</b>
</label>
</section>

<section>
<label class="input">
<i class="icon-append fa fa-envelope"></i>
<input type="email" name="email" placeholder="Email address" [value]="email">
<b class="tooltip tooltip-bottom-right">Enter Email Address</b>
</label>
</section>

<section>
<label>
Roles
</label>
<div>
<ng-select
[multiple]="true"
[items]="roles"
[disabled]="disabled"
(data)="refreshValue($event)"
(selected)="selected($event)"
(removed)="removed($event)"
placeholder="No roles assign">
</ng-select>
</div>
</section>

<!--<section>
<label>
Groups
</label>
<div>
<ng-select
[multiple]="true"
[items]="groups"
[disabled]="disabled"
(data)="refreshValue($event)"
(selected)="selected($event)"
(removed)="removed($event)"
placeholder="No groups assign">
</ng-select>
</div>
</section>-->
</fieldset>
<footer>
<button type="reset" class="btn-u">Cancel</button>
<button type="submit" class="btn-u" [disabled]="!userEdit.form.valid">Save</button>
</footer>
</form>
<!-- End Reg-Form -->
</div>

</div><!--/end row-->
<!-- JS Global Compulsory -->




Answer

There is an issue on github about this problem.

The workaround found by jkwiz is to wrap your select in an *ngIf div, making your select delayed because it will only be created once the query got your data:

    ...
    ...
           <section>
                <label>
                    Roles
                </label>
                <div *ngIf="roles.length > 0">
                    <ng-select 
                               [multiple]="true"
                               [items]="roles"
                               [disabled]="disabled"
                               (data)="refreshValue($event)"
                               (selected)="selected($event)"
                               (removed)="removed($event)"
                               placeholder="No roles assign">
                    </ng-select>
                </div>
            </section>
    ...
    ...

Problem with this is that you can't add row to your select dynamicaly, and it seems like it's an issue on ng2-select and it won't be fixed imediately I guess, since the issue is a bit old, even if it's a critical feature.