The default selected item in Material Select does not function properly on the second attempt

Is there a way to reset an Angular Material Select Component to its default value after manually changing it on the UI screen? It seems to work fine during initialization but not after manual changes.

I am attempting to create a button that will revert the Select Component back to its default value. I have looked into using NgOnChanges, but I am already utilizing get setters.

HTML:

<div class="dropdown-cont">
    <mat-form-field appearance="outline">
        <mat-label>{{label}}</mat-label>
        <mat-select
            disableOptionCentering
            [disabled]="disabled"
            [ngStyle]="styles"
            [(ngModel)]="selectedItem"
            (selectionChange)="selectedItemChanged($event)"
            >
            <mat-option [value]="defaultItem[txtValue]">{{defaultItem[txtField]}}</mat-option>
            <mat-option
                *ngFor="let item of listItems"
                [value]="item[txtValue]"
            >
            {{item[txtField]}}
            </mat-option>
        </mat-select>
        <mat-hint>{{hint}}</mat-hint>
    </mat-form-field>
</div>

Typescript:

import { Component, OnInit, Input, EventEmitter, Output, forwardRef } from '@angular/core';
import { DropdownItem, DropdownComponent } from '../dropdown/dropdown.component';
import { NG_VALUE_ACCESSOR } from '@angular/forms';

@Component({
  selector: 'app-drop-down',
  templateUrl: './drop-down.component.html',
  styleUrls: ['./drop-down.component.scss'],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => DropdownComponent),
      multi: true
    }
  ]
})

export class DropDownComponent implements OnInit {
  ngOnInit() {
  }

  //#region Members

  private _listItems = [];

  onChange: any = () => { };

  onTouch: any = () => { };

  //#endregion

  //#region Inputs

  @Input()
  set listItems(data: Array<DropdownItem>) {
    this._listItems = data;
    this.selectedItem = undefined;
  }
  get listItems() {
    return this._listItems;
  }
  @Input() label = '';
  @Input() styles: any = {};
  @Input() txtField: any;
  @Input() txtValue: any;
  @Input() disabled: boolean;
  @Input() defaultItem: object;
  @Input() selectedItem: DropdownItem;
  @Input() primitive = false;
  @Input() hint = '';
  //#endregion

  //#region Outputs

  @Output() selectedItemOutput = new EventEmitter();

  //#endregion

  //#region ControlValueAccessor

  set value(val) {
    this.selectedItem = val;

    this.onChange(val);

    this.onTouch(val);
  }

  writeValue(obj: any): void {
    this.selectedItem = obj;
    this.value = obj;
  }
  registerOnChange(fn: any): void {
    this.onChange = fn;
  }
  registerOnTouched(fn: any): void {
    this.onTouch = fn;
  }
  setDisabledState?(isDisabled: boolean): void {
    this.disabled = isDisabled;
  }

  //#endregion

  //#region Event Handlers

  selectedItemChanged(selectItem) {
    this.onChange();
    let outputData: any;
    if (selectItem.value == this.defaultItem[this.txtValue]) {
      outputData = this.defaultItem;
    } else {
      outputData = this.listItems.find(x => x[this.txtValue] == selectItem.value);
    }

    this.selectedItemOutput.emit(outputData);
  }

  //#endregion

}

Answer №1

Check out this StackBlitz Link

<mat-select
        [(ngModel)]="selectedItem.txtValue"
        (selectionChange)="selectedItemChanged($event)" >
        <mat-option [value]="selectedItem.txtValue">
                 {{selectedItem.txtField}}
        </mat-option>
        <mat-option *ngFor="let item of listItems" [value]="item.txtValue" >
                 {{item.txtField}}
        </mat-option>
</mat-select>

 <button (click)="defaultState()" > Default State </button>

Next, in your component.ts file...

selectedItem = {txtValue:'d', txtField: 'default'};
listItems =[{
   txtValue: '1',
   txtField: 'one'
}]

selectedItemChanged(event){
   console.log(event.value)
}
// This function restores default state of dropDown select when button is clicked
defaultState(){
  this.selectedItem = {txtValue:'d', txtField: 'default'};
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Utilize TypeScript in creating a Chrome extension to fetch elements by their ID

I'm currently working on a Chrome extension using Angular and Typescript, and I have encountered an issue with accessing the document element by its id from the active tab. While this works perfectly fine in JavaScript, I am facing difficulties in ach ...

Redis Cache expiry concept

Recently, I've come across an issue with ioredis where I have been setting a key and expiration for that key in my code. Here's a snippet of what my code looks like: let temp1 = acct.limit; let txn = array.length; let cache = new ioredis(); // p ...

The scss function is returning an invalid property value

In my Angular project, I have organized my scss files/folders in the following way: 1) Settings - containing color settings and functions for the project 2) Files and folders defining variables such as fonts, widths, etc. for components and pages 3) Fil ...

MD Autocomplete Component: An Input Inside

Currently, I am working on implementing a feature where users can enter different search terms in an input field within Angular Material's autocomplete component. The issue arises when the user clicks on the input option as it closes the autocomplete ...

Svelte with Typescript: Uncovering the Types of Props

Issue: I am trying to create a function that can take a component as the first argument and its props as the second argument in a generic manner import Modal from "./Modal.svelte"; function openModal(component: typeof Modal, componentProps: ...

Generate detailed documentation for the functional tests conducted by Intern 4 with automated tools

I need to automatically generate documentation for my Intern 4 functional tests. I attempted using typedoc, which worked well when parsing my object page functions. However, it failed when working with functional test suites like the one below: /** * Thi ...

What are effective strategies for troubleshooting Dependency Injection problems in nest.js?

Can someone explain the process of importing a third-party library into NestJS using Dependency Injection? Let's say we have a class called AuthService: export class AuthService { constructor( @Inject(constants.JWT) private jsonWebToken: any, ...

Accessing nested JSON objects with key-value pairs

I have a method in my .ts file that displays keys but doesn't fetch nested JSON data. generateArr(obj) { return Object.keys(obj).map((key) => { console.log(key, obj[key]); return {key: key, value: obj[key]}; }); } Here is the HTML code I&apo ...

The service has terminated unexpectedly because of signal: Ended prematurely: 9

I'm encountering the error 'Service exited due to signal: Killed: 9' and am unable to launch my app. I've come across information suggesting that this may be caused by memory leaks or a lengthy startup time for the app. In all honesty, ...

Can you confirm if npm is successfully connecting through a proxy from Visual Studio 2015?

My first attempt at building an Angular site is hitting a roadblock – I can't seem to restore the json packages using NPM. It looks like there's a proxy issue since I'm behind a corporate firewall. Now, I'm trying to troubleshoot and ...

Locate and retrieve the item that appears most often in a given array

In order to determine the mode of an array consisting of integer numbers only, I must create a function named findMode. If the array is empty, the function should return 0. Otherwise, it should return the element that occurs most frequently in the array. I ...

Encountering errors during 'npm i' - issues arising from unresolved dependency tree

Recently, I have been facing issues with running npm i as it keeps failing and showing an error. The project is using Angular 15 without any previous errors, so it's puzzling why there is suddenly a complaint about Angular 16. npm ERR! code ERESOLVE n ...

Boost Page Speed with Angular

Currently, I am working on a project using Angular and encountered an issue with testing the page speed on GTmetrix. Despite generating the build with the command ng build --prod--aot, the file size is 1.9mb, leading to a low speed in GTmetrix's analy ...

Unable to utilize a generic model in mongoose due to the error: The argument 'x' is not compatible with the parameter type MongooseFilterQuery

Attempting to include a generic Mongoose model as a parameter in a function is my current challenge. import mongoose, { Document, Model, Schema } from 'mongoose'; interface User { name: string; age: number; favouriteAnimal: string; ...

How can Angular 2 populate forms with data retrieved from a promise in a database?

I'm currently navigating through the world of Angular and Firebase, and I’ve hit a roadblock when it comes to populating my forms with data from Firebase promises. Understanding how to work with promises versus observables is also proving to be a ch ...

Accessing the ViewModel property of a parent component from the ViewModel of its child in Aurelia

Having a scenario with two distinct components: <parent-component type="permanent"> <div child-component></div> </parent-component> class ParentComponentCustomElement { @bindable public type: string = "permanent"; } clas ...

What is the proper way to utilize queries in BlitzJS?

I am attempting to extract data from a table by filtering based on the relationship with the Blitzjs framework. However, I am facing difficulties using queries as it seems to be the only option available. Every time I try to call the quer ...

Change the ddmmyy date string to dd/mm/yyyy format using TypeScript

When I use the date picker onchange method, the date is passed as a string like ddmmyyyy (20102020) to dd/mm/yyyy. I am unsure of how to convert the date format from ddmmyyyy to dd/mm/yyyy. In the CustomDateParserFormatter, the string needs to be converted ...

Incorporating Bloodhound into an Angular 2 CLI project

I have been working on integrating Bloodhound.js into an Angular 2 project that utilizes Angular 2 CLI. Currently, I have successfully implemented jQuery by following these steps: Installed jQuery using npm install jquery --save Installed jQuery Type ...

I rely on the angular-responsive-carousel library for my project, but unfortunately, I am unable to customize the arrow and dots

When it comes to CSS, I utilize ng deep style in Angular 10 to make changes for browser CSS. However, I am facing an issue where the problem is not being resolved by my CSS code. Here is a snippet of my code: > ::ngdeep .carousel-arrow { > b ...