Sign in


Sign up


Material Select Issues with binding

MDB SupportCategory: MDB AngularMaterial Select Issues with binding
stgiaf Pro User asked 2 weeks ago in MDB pro, version:5.1.2

Could you please provide an example of material select with 2 way binding and values coming from an API?

It seems that in 2 way binding the material select triggers the change event when rendered, and ruins the object that it is bound to when loaded causing and undefined value.

the code is following , together with a normal select element that is working fine:

ts file

import { Observable } from ‘rxjs/Observable’;
import { DepartmentService } from ‘./../department.service’;
import { UserService } from ‘./../user.service’;
//import { User } from ‘./../models/user.type’;
import { Component, OnInit } from ‘@angular/core’;
import { ActivatedRoute } from ‘@angular/router’;
import { IUser } from ‘../models/user’;
import ‘rxjs/add/observable/forkJoin’;
@Component({
selector:’app-user-card’,
templateUrl:’./user-card.component.html’,
styleUrls: [‘./user-card.component.scss’]
})
export class UserCardComponent implements OnInit {
loading:boolean;
privatedepartments= [];
privateuser:IUser=
{
id:0,
name:’ ‘,
department : {
id :”0″,
name:’ ‘
}
};
constructor(privateroute:ActivatedRoute,
privateuserService:UserService,
privatedepartmentService:DepartmentService)
{
this.route.params.subscribe ( p=> {
this.user.id=+p[‘id’] ||0;
})
}
ngOnInit() {
this.loading=true;
varsources= [
this.departmentService.getDepartments(),
this.userService.GetUser(this.user.id)
]
Observable.forkJoin(sources).subscribe( data=> {
console.log(data);
data[0].forEach(element=> {
this.departments.push(
{‘value’: element.id,
‘label’ :element.name
});
});
//this.departments = this.departments.slice();
if (this.user.department.id) {
console.log(‘Department exists’);
}
this.setUser(data[1]);
this.loading=false;
});
}
AddDepartment(){
//this.departments.push({value:”2″, label:”Test”})
//console.log(this.departments);
//this.departments = this.departments.slice();
//this.user.department.id=”2″;
console.log(this.user);
}
SelectOnChange(event) {
console.log(this.user);
console.log(event);
}
setUser( user:IUser){
this.user.id=user.id;
this.user.name=user.name;
this.user.department.id=user.department.id ;
this.user.department.name=user.department.name
console.log(“user:” , this.user)
}
}

html

<div class=”row”>
<divclass=col-md-4>
<divclass=”card card-cascade narrower”>
<divclass=”view card-header text-center blue-gradient white-text”>
<h4class=”h4-responsive mb-0″>User Card</h4>
</div>
<divclass=”card-body”>
<div *ngIf=”loading”class=”progress primary-color-dark”>
<divclass=”indeterminate”></div>
</div>
<form>
<divclass=”md-form mt-5″>
<iclass=”fa fa-user prefix gray-text”></i>
<inputmdbActivetype=”text”id=”name”name=”name” [(ngModel)]=”user.name”>
<labelclass=”active”for=”name”>Your Name</label>
</div>
<divclass=”md-form”>
<divclass=”row”>
<divclass=”col-md-6″>
<mdb-selectname=”department” [options]=”departments” [(ngModel)]=”user.department.id”placeholder=”Choose Department”></mdb-select>
<labelclass=”active”>Department</label>
</div>
</div>
</div>
<buttonclass=”btn btn-primary” (click)=”AddDepartment()”>Add Department</button>
</form>
</div>
</div>
</div>
<divclass=col-md-4>
<divclass=”card card-cascade narrower”>
<divclass=”view card-header text-center blue-gradient white-text”>
<h4class=”h4-responsive mb-0″>User Card</h4>
</div>
<divclass=”card-body”>
<div *ngIf=”loading”class=”progress primary-color-dark”>
<divclass=”indeterminate”></div>
</div>
<form>
<divclass=”md-form mt-5″>
<iclass=”fa fa-user prefix gray-text”></i>
<inputmdbActivetype=”text”id=”name”name=”name” [(ngModel)]=”user.name”>
<labelclass=”active”for=”name”>Your Name</label>
</div>
<divclass=”md-form”>
<divclass=”row”>
<divclass=”col-md-6″>
<labelclass=”active”>Department</label>
</div>
</div>
</div>
<buttonclass=”btn btn-primary” (click)=”AddDepartment()”>Add Department</button>
</form>
</div>
</div>
</div>
</div>
<select class=”browser-default mdb-select” [(ngModel)]=”user.department.id” name=”department”>
<option *ngFor=”let d of departments”value=”{{d.value}}”>{{ d.label}}</option>
</select>

Additionally it seems that mbd-select class cannot be applied to normal select element.

2 Answers
Damian Gemza answered 2 weeks ago

Hello stgiaf,

It’s looks like that i’ve posted you solution of this problem at your’s email. Please check it. For now i will mark post as resolved.

Best Regards,

Damian

stgiaf Pro User replied 2 weeks ago

Hello Damian,
Did you try to recieve the data via a service asynchronously, and the behavior of your material select was the same as a normal select?
I my case, when everything is completed the variable that ngModel is bound to is “undefined” , although from the service it comes correctly and also the values exists in the [options] input. This happens, possibly because at the time of rendering the control, the observable has not yet been completed and then the values are lost somehow. if you remove two way binding and do it with one way it works.

The issue here is that mdb material select works differently from normal select element.

If you have a working example of material select with values coming from a service (http) via objssrvable and values bound to a model of yours with ngModel, then supply it to me , so that I can replicate.

Damian Gemza replied 2 weeks ago

Dear stgiaf,
I’ve tried to reproduce your error following closely your steps, but for me, everything is working as expected.
Could you tell me one more time, which thing doesn’t work for you well, in which way works now, and what is your expected behavior of this thing?
Best Regards,
Damian

stgiaf Pro User replied 2 weeks ago

Hello Damian,
No this is something different, with material-select

Damian Gemza answered 1 week ago

Hello stgiaf,

Yes, I’m obtaining data from fake API in asynchronous way.

Here’s my code, so u can check it:

.html file:

<div class="row">

<div class="col-md-6 mx-auto my-5">

<mdb-select [(ngModel)]="choosen.department.id" [options]="optionsSelect" placeholder="Choose your option"></mdb-select>

<label>Example label</label>

</div>

</div>

<div class="row">

<divclass="col-md-6 mx-auto my-5">

<div>

OPCJA: {{choosen.department.id}}

</div>

</div>

</div>
.ts file:
optionsSelect: Array<any>;

privatechoosen= {

id:0,

title:'',

department: {

id:0,

}

};

url='https://jsonplaceholder.typicode.com/posts';

constructor(privatehttp:Http) { }

getData() {

returnthis.http.get(this.url).map(res=>res.json());

}

ngOnInit() {

this.getData().subscribe(next=> {

console.log(next);

this.optionsSelect= [

{ value: next[0].id, label: next[0].title },

{ value: next[1].id, label: next[1].title },

{ value: next[2].id, label: next[2].title },

{ value: next[3].id, label: next[3].title },

{ value: next[4].id, label: next[4].title },

{ value: next[5].id, label: next[5].title },

];

});

}

}
For me, everything works fine.
Best Regards,
Damian