0

Goal: Set default value for a dropdown that changes the address of the site the user is on /en/ or /es/ for English or Spanish

Problem: After going through documentation and through every SO article I could find such as Angular 2 Dropdown Options Default Value, none of the variations seem to work.

What is wrong? And do I need a form/mat-form or is there a simpler way to do this?

What I've tried: Here are some of the variations of what I've tried in the HTML and in the TypeScript:

<mat-select (selectionChange)="doSomething($event)" [value]="language"> 
<mat-select (selectionChange)="doSomething($event)" [value]="English">  
<mat-select (selectionChange)="doSomething($event)" [(ngModel)]='defaultLanguage'>

HTML:

<form [formGroup]="_siteForm">
      <mat-form-field class="right">
          <mat-select (selectionChange)="doSomething($event)" [(ngModel)]='defaultLanguage'>
              <mat-option *ngFor="let language of languages" [value]="language">
                  {{language.viewValue}}
              </mat-option>
          </mat-select>
      </mat-form-field>
</form>

TypeScript:

public _siteForm             : FormGroup;
this._siteForm = fb.group({
            'languages' : ['']
        });
public languages = [
  { value: "en", viewValue: 'English' },
  { value: "es", viewValue: 'Spanish' }
   ];

public defaultLanguage          : string = "English";

if (this.localeId == "en") { this._siteForm.controls["languages"].setValue(this.languages.filter(item => item.value === 'en')[0].viewValue); }
else { this._siteForm.controls["languages"].setValue(this.languages.filter(item => item.value === 'es')[0].viewValue); }

Alternate

this._siteForm.setValue({ languages: "en" });
angleUr
  • 449
  • 1
  • 8
  • 27

3 Answers3

0

The reason could be the type of values you are setting as default and the type of objects you are looping through.

The type is string here:

<mat-select (selectionChange)="doSomething($event)" [value]="language"> 
<mat-select (selectionChange)="doSomething($event)" [value]="English">

But it's JSON object here:

<mat-option *ngFor="let language of languages" [value]="language">
     {{language.viewValue}}
</mat-option>

Make both the same type, both JSON objects or both strings.

If you use [value]="languages[0]" it would set default value using the first element of the languages array.

https://github.com/angular/components/issues/7771#issuecomment-336482394

Maihan Nijat
  • 9,054
  • 11
  • 62
  • 110
  • .the mat-option has value=language and also the mat-select. Are you saying value is string for mat-option? I've used this format in other areas without problem. Why is it not working here? – angleUr Nov 27 '19 at 20:43
  • Thanks. Shouldn't the setValue method have changed that though? How would I set it to JSON? The syntax in your comment looks identical. – angleUr Nov 27 '19 at 20:46
  • I tried patchValue as well but that did not work. Adding {{language.viewValue}} to the mat-select brakes the page. – angleUr Nov 27 '19 at 20:59
  • 1
    @angleUr @angleUr Do this to mat-select: `[value]="languages[0]"` – Maihan Nijat Nov 27 '19 at 21:08
  • I did this with languages[i] so it could be dynamic, and it worked. – angleUr Nov 29 '19 at 16:59
  • Can you update your answer to include what you have in the comment? As is, it doesnt work, but your comment worked. – angleUr Nov 29 '19 at 17:55
0

Try this:

public languages = [
  { value: "en", viewValue: 'English' },
  { value: "es", viewValue: 'Spanish' }
   ];

public defaultLanguage = languages[0]; // or languages[1]

What I noticed right away is your are trying to make your ngModel, which is a string match your [value] which is an object

<mat-select (selectionChange)="doSomething($event)" [(ngModel)]='defaultLanguage'>
     <mat-option *ngFor="let language of languages" [value]="language">
          {{language.viewValue}}
     </mat-option>
</mat-select>
Damian C
  • 2,111
  • 2
  • 15
  • 17
0

You probably want to use something like this:

<mat-option *ngFor="let language of languages" [value]="language.value">
    {{language.viewValue}}
</mat-option>

Then set the default language to one of those values:

public defaultLanguage: String = "en";

This way the options are simple strings rather than JSON making them easily comparable. Currently your defaultLanguage variable doesn't match either of the options.

emassie
  • 129
  • 9