Topic: How to detect all changes to input value mdb-auto-completer
Firstly, I need to mention that I use 7.5.4 and I can't upgrade to 8.x since my project is in production and the number of style changes required is overwhelming.
I've created the next mdb-auto-completer shell component I'm going to use in my application (with some debug code included):
import { Component, Input, ViewChild, ElementRef, OnInit } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import { startWith, map } from 'rxjs/operators';
import { MdbAutoCompleterComponent } from 'ng-uikit-pro-standard';
@Component({
selector: 'app-modal-auto-completer',
template: `
<div class="md-form">
<input #autoCompleteInput
type="text"
class="completer-input form-control mdb-autocomplete"
[ngModel]="autoCompleteValue | async"
(change)="valueChanged($event)"
(ngModelChange)="autoCompleteValue.next($event); log($event)"
[mdbAutoCompleter]="autoCompleter"
placeholder="{{placeholder}}"
/>
<mdb-auto-completer #autoCompleter="mdbAutoCompleter" textNoResults="{{emptyResult}}">
<mdb-option *ngFor="let option of optionList | async" [value]="option">
{{option}}
</mdb-option>
</mdb-auto-completer>
</div>
`,
styles: []
})
export class ModalAutoCompleterComponent implements OnInit {
@ViewChild("autoCompleter") autoCompleter: MdbAutoCompleterComponent;
@ViewChild("autoCompleteInput") autoCompleteInput: ElementRef;
@Input() placeholder: string;
@Input() emptyResult = "No results found";
@Input() selector: (search: string) => string[];
autoCompleteValue = new Subject();
optionList: Observable<string[]>;
constructor() { }
ngOnInit() {
this.optionList = this.autoCompleteValue.pipe(
startWith(''),
map((value: string) => this.selector(value))
);
}
valueChanged(event: any) {
console.log("Changed", event);
}
log(event: any) {
console.log("Event", event);
console.log("Value", this.autoCompleter.getSelectedItem());
console.log("Input value", this.autoCompleteInput.nativeElement.value);
}
}
So I have an input "selector" function that allows me to reuse the component in different places of my application and still hide all pipes, subjects and object things. I was really surprised that for some reason (ngModelChange) is never triggered for the main workflow with the auto completer, that is, to select some option from the list. Also (change) is never triggered at all. What then is way to detect the change of the input value (originated from any source - selection of an option or from manual input)? Using subscriptions for the case is just nonsense since it's expected that the component should work the same as any ordinary input -> it's passed a pointer to some data -> it changes the data on input changes -> at some point all data is submitted without any manual calls to the auto completer or checking it's value.
Thank you in advance for the reply.
FREE CONSULTATION
Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.
Open
- User: Pro
- Premium support: No
- Technology: MDB Angular
- MDB Version: 7.5.4
- Device: PC
- Browser: Chrome
- OS: Windows 10 x64
- Provided sample code: No
- Provided link: No
Arsenii pro commented 5 years ago
This one also doesn't trigger on option selection: this.autoCompleteValue.subscribe((item) => { console.log("Item", item); }, (err) => { console.log("Error", err); });
Konrad Stępień staff commented 5 years ago
Hi @Arsenii,
Did you try to use
select
&selected
outputs in your code?Please visit autocomplete API documentatnion for more info. If you have still a problem, please tell me about that.
Best, Konrad.
Arsenii pro commented 5 years ago
Hi @Konrad Stępień Thank you for your reply!
I figured out how to create event emitter reflecting every change needed for me. But then during testing, I found that when you clear the selected option (press "times" icon), duplication of ngModel update happens, that is, ngModel is updated not once but twice. If you clear the value one more time, ngModel updates 3 times and so on - so there is some cycle-reference and unstable behaviour inside the component. Unfortunately, at this point I realized that I shouldn't use the component at all and added an external ng-select library to my project to accomplish my goal.
Regards, Arsenii