I have a simple select with an ngFor and the select box is empty until I type into one of the other fields and then it magically shows the data even though I know it completed the data call previously.
My view
<div class="form-group col-md-3">
<label for="payerId">PayerId</label>
<select class="form-control">
<option *ngFor="#item of model.payers">{{item.HealthPlanName}}</option>
</select>
</div>
<div class="form-group col-md-3">
<label for="providerType">Provider Type</label>
<input type="text" class="form-control" [(ngModel)]="model.providerType"/>
</div>
My Component
import {Component, Injectable, OnInit, View} from "angular2/core";
import {CORE_DIRECTIVES, FORM_DIRECTIVES, NgForm, NgFormControl, NgFor} from "angular2/common";
import {CoverageService} from "../../services/coverage/coverage.services";
import "rxjs/Rx";
#Component({
selector: "coverage",
providers: [CoverageService]
})
#View({
templateUrl: "/Scripts/appScripts/components/coverage/coverage.html",
directives: [CORE_DIRECTIVES, FORM_DIRECTIVES, NgForm, NgFormControl, NgFor, PayerSelector]
})
export class CoverageComponent implements OnInit {
model = new CoverageRequest();
constructor(private coverageService: CoverageService) {}
ngOnInit() {
this.getPayers();
}
getPayers() {
this.coverageService.getPayers()
.subscribe(resp => {
this.model.payers = resp;
});
}
}
Really scratching my head.
Here are the libraries I am using:
"dependencies": {
"angular2": "2.0.0-beta.0",
"systemjs": "^0.19.20",
"es6-promise": "^3.0.2",
"es6-shim": "^0.33.3",
"reflect-metadata": "0.1.2",
"rxjs": "5.0.0-beta.0",
"zone.js": "0.5.10"
}
My Service
import {Http, Response} from "angular2/http";
import {Injectable} from "angular2/core";
import {COVERAGE_BASE} from "../../config";
import "rxjs/Rx";
#Injectable()
export class CoverageService {
constructor(public http: Http) {
}
getPayers(): any {
return this.http.get(COVERAGE_BASE + "/Payers")
.map((response: Response) => response.json());
}
}
Data
[{
"Id": 3817,
"ProviderId": 2,
"ApiPayerId": "00028",
"HealthPlanName": "Georgia Medicaid",
"Type": null,
"PayerSynonyms": null
}, {
"Id": 3818,
"ProviderId": 2,
"ApiPayerId": "00143",
"HealthPlanName": "J. F. Molloy and Associates Inc.",
"Type": null,
"PayerSynonyms": null
}]
Try initiating the model in ngOnInit instead of directly in the class. You will need to use the elvis operator in the view, because the model initially will be undefined. Read more about the elvis operator here: https://angular.io/docs/ts/latest/guide/template-syntax.html#!#sts=The%20Elvis%20operator%20(%20%3F.%20)%20and%20null%20property%20paths
I am not entirely sure but i think it should work.
Related
Angular version: 5.0.0
angular/material version: 5.2.4
I've got this form:
<form #updateForm="ngForm">
<mat-form-field>
<input type="text" matInput [formControl]="studentFormControl [matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete">
<mat-option *ngFor="let student of students" [value]="student">
{{student}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</form>
And I've got this component:
import { FormGroup, FormControl, FormsModule, ReactiveFormsModule } from '#angular/forms';
import { MatInputModule, MatAutocompleteModule, MatFormFieldModule } from '#angular/material';
export class DashboardComponent implements OnInit {
this.studentFormControl = new FormControl();
this.students = ['hi', 'hello'];
...
}
Although the form shows up, the autocomplete box remains dimensionless without options rendered within:
screenshot of input/autocomplete box
It should be noted as well that the form is nested within an ngbModal. Any ideas what could be happening here?
So I'm no expert here, but from what I understand, the autocomplete function requires an observable of sorts, at least if you want to be able to filter results as you type, to be selected. Since you are using an array you need to first turn it into an observable. As your array is loaded immediately you would need to use RXJS's subjects and more specifically the BehaviorSubject.
Once it becomes an observable you can then call it using the asyncpipe on your form.
This is not to say you couldn't have done it with an array and not used the asyncPipe, however that array would have to be loaded in OnInit.
See the example for both
import { Observable, from, Subscription, BehaviorSubject } from 'rxjs';
import { Component, OnInit } from '#angular/core';
import { FormGroup, FormControl, FormsModule, ReactiveFormsModule } from '#angular/forms';
import { MatInputModule, MatAutocompleteModule, MatFormFieldModule } from '#angular/material';
#Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.css']
})
export class TestComponent implements OnInit {
studentFormControl = new FormControl();
studentFormControl1 = new FormControl();
array = ['test','one','two'];
array1=[];
arrayObs: Observable<any>;
arrayBehObs = new BehaviorSubject(this.array);
constructor() { }
ngOnInit() {
this.array1.push('test','one','two');
this.arrayObs = this.returnAsObs();
}
private returnAsObs() {
return this.arrayBehObs.asObservable();
}
}
<form #updateForm="ngForm">
<input type="text" matInput [formControl]="studentFormControl" [matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete">
<mat-option *ngFor="let student of arrayObs|async" [value]="student">
{{student}}
</mat-option>
</mat-autocomplete>
<input type="text" matInput [formControl]="studentFormControl1" [matAutocomplete]="auto1">
<mat-autocomplete #auto1="matAutocomplete">
<mat-option *ngFor="let student of array1" [value]="student">
{{student}}
</mat-option>
</mat-autocomplete>
</form>
At first I have added the ReactiveFormModule in app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { RouterModule, Routes} from '#angular/router';
import { ReactiveFormsModule } from '#angular/forms';
import { AppComponent } from './app.component';
import { NewproducComponent } from './comp/newproduc/newproduc.component';
import { ProductsComponent } from './comp/products/products.component';
import { SidebarComponent } from './comp/sidebar/sidebar.component';
import { MenubarComponent } from './comp/menubar/menubar.component';
const appRoutes: Routes = [
{ path : '' , component : ProductsComponent},
{ path : 'newproduct' , component : NewproducComponent}
];
#NgModule({
declarations: [
AppComponent,
NewproducComponent,
ProductsComponent,
SidebarComponent,
MenubarComponent
],
imports: [
BrowserModule,
ReactiveFormsModule,
RouterModule.forRoot(appRoutes)
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {
}
the app.component.html contanis
<app-menubar></app-menubar>
<app-sidebar></app-sidebar>
<div class="container">
<router-outlet></router-outlet>
</div>
the newproduc.component.html contains
<div id="main-body">
<div class="main-body-header">
<span>New Product</span>
<button type="button">Close</button>
<button type="button">Save</button>
</div>
<div class="main-body-component">
<div class="container">
<form>
</form>
</div>
</div>
</div>
when adding this form tag i am getting the following error
Error in browser console
Whenever, I remove the form tag the error removes. I am not sure where i made the error. Please help me in solving the issue. I have stacked for last 2 days.
Do:
<form [formGroup]="form">
Because you are importing ReactiveFormsModule, the <form> tag must have a formGroup.
Short summary of what i actually want to do.
If i click on the heroes table. I need to pass the heroes data from the row clicked to a Modal.
I read that there are two ways to get Data into a Modal. (NGMODAL)
With #Input and #Output or through a shared Service.
But it doesn't matter which way I am using. The modal opens (and fetches data) always before the data is passed.
I've simply got a table in which all my heroes are displayed.
On a Click on the delete button in a table row I wan't to open the modal and pass the data from my table row. (I want to pass the whole hero, but shouldn't be a difference to just passing the name of the hero).
After that i want to show.
Do you really want to delete hero with name...?
[Cancel], [Yes, Delete] . Onclick on the Yes, Delete Button I want to delete the hero.
At the moment I can't even display the heroes name I want to delete
I hope anyone can tell my what I can do and how.
Thank you.
Here is my code:
Shows my Heroes: hero.component.html
<div class="container">
<h2>Heroes</h2>
<input type="text" placeholder="Suchbegriff eingeben" class="form-control has-float-label" [(ngModel)]="filter" >
<br>
<div *ngIf="heroes">
<table class="heroes table table-hover table table-striped">
<thead>
<tr>
<th>Name</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let hero of heroes | filter:filter:'name':'name'">
<td>{{hero.name}}</td>
// I could use (click)="pusHero(hero)" and open the modal afterwars. Than i would get the right data through input. But when i click to open the modal first there is no data, or the data from the row clicked before
<td>
<ngbd-modal-component (click)="selectRow(hero) [(delhero)]="delhero""></ngbd-modal-component> </td>
</tbody>
</table>
</div>
</div>
heroes.component.ts
import { Component, OnInit, ViewEncapsulation , Input , EventEmitter} from '#angular/core';
import { Hero } from '../../model/hero';
import { HeroService } from '../hero.service';
import { CommonModule } from '#angular/common';
import { Observable } from 'rxjs/Observable';
import { Response } from '#angular/http/src/static_response';
// For use of map
import 'rxjs/Rx';
// Für Pipe und Suche in Liste
import { Pipe, PipeTransform } from '#angular/core';
import { FilterPipe } from '../../pipes/filter.pipe';
// Component Decorator imported from Component
#Component({
// Unique Selector
selector: 'app-hero',
// URL of Template
templateUrl: './hero.component.html',
// URL of stylesheet
styleUrls: ['./hero.component.css']
// encapsulation: ViewEncapsulation.None
})
export class HeroesComponent implements OnInit {
heroes: Observable<Hero[]>;
hero: Hero;
filter = '';
// Is Input for Child Component. In this case modal
delhero: Hero;
constructor(
private heroService: HeroService,
// Modal Service
// private modalService: NgbModal,
// private ngbdModalComponent: NgbdModalComponent,
// private ngbdModalContent: NgbdModalContent,
) {
// this.searchableList = ['name','age']
}
selectRow(hero): void {
console.log("Select the tables data");
console.log(hero);
this.heroService.selectRow(hero);
}
}
Hero Service
import { Injectable } from '#angular/core';
import { HttpClient, HttpHeaders } from '#angular/common/http';
import { HttpResponse } from '#angular/common/http';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { catchError, map, tap } from 'rxjs/operators';
import { Hero } from '../model/hero';
import { MessageService } from '../message.service';
import { Response } from '#angular/http/src/static_response';
// For use of map
import 'rxjs/Rx';
import { headersToString } from 'selenium-webdriver/http';
const httpOptions = {
headers: new HttpHeaders(
{
'Content-Type': 'application/json'
}
)
};
#Injectable()
export class HeroService {
private hero: Hero;
constructor(private http: HttpClient, private messageService: MessageService) { }
selectRow(input){
this.hero = input;
}
getRow(){
console.log(this.hero);
return this.hero;
}
}
My Modal
modal.component.html
<button class="btn btn-danger btn-xs more" (click)="open()"> <span class="fa fa-trash"></span></button>
modal.component.ts
import { Component, Input, EventEmitter, SimpleChange, Output, OnInit } from '#angular/core';
import { NgbModal, NgbActiveModal } from '#ng-bootstrap/ng-bootstrap';
import { NgbdModalContent } from './modal.content.component';
import { Hero } from '../../model/hero';
import { HeroService } from '../../hero/hero.service';
// Modal Component
#Component({
selector: 'ngbd-modal-component',
templateUrl: './modal.component.html'
})
export class NgbdModalComponent {
// #Input() delhero: Hero;
// hero: Hero;
// #Output() getDeleteHero = new EventEmitter();
name = '';
constructor(private modalService: NgbModal,
private heroService: HeroService) {}
ngOnInit(){
// this.open();
// console.log(this.delhero);
}
open() {
var name = this.heroService.getRow();
// this.getDeleteHero.emit();
console.log("Modal Component hero");
// console.log(this.delhero);
this.name = this.heroService.getRow().name;
const modalRef = this.modalService.open(NgbdModalContent);
modalRef.componentInstance.name = name;
}
delete(){
console.log("Delete Hero through Hero Service");
}
}
modal.content.component.html
<div class="modal-header ">
<h4 class="modal-title">Delete Hero?</h4>
<button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross click')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Delete Hero with Name: {{name}}?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" (click)="activeModal.close('Close click')">No, do not delete</button>
<button type="button" class="btn btn-primary">Ja, löschen</button>
</div>
modal.content.component.ts
import { Component, Input, EventEmitter } from '#angular/core';
import { NgbModal, NgbActiveModal } from '#ng-bootstrap/ng-bootstrap';
import { HeroService } from '../../hero/hero.service';
import { Hero } from '../../model/hero';
// Modal Content
#Component({
selector: 'ngbd-modal-content',
templateUrl: './modal.content.component.html'
// styleUrls: ['./modal.content.component.css']
})
export class NgbdModalContent {
// #Input() Hero;
name = "";
constructor(
public activeModal: NgbActiveModal,
privateheroService: HeroService
) {}
ngOnInit() {
//Called after the constructor, initializing input properties, and the first call to ngOnChanges.
//Add 'implements OnInit' to the class.
console.log("NG On Init ModalsContent");
this.name = this.heroService.getRow().name;
console.log(this.name);
}
}
Not sure if this helps but I found this after having the same problem.
I ended up with working code. Sorry it's not your code but I was having trouble following it. I had to set a variable and pass it in via the click code:
HTML:
<ng-template #content let-c="close" let-d="dismiss">
<div class="modal-header">
<h4 class="modal-title">Option Entry</h4>
<button type="button" class="close" aria-label="Close" (click)="d('Cross click')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form>
<div class="form-group">
<label class="control-form-label" for="optDescription">Description:</label>
<input type="text" class="form-control" name="description" ngModel id="optDescription" [(ngModel)]="editOption">
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-dark" (click)="c('Close click')">Update</button>
</div>
</ng-template>
<div *ngIf='optionList && optionList.length'>
<div *ngFor='let opt of optionList'>
<ngb-accordion #acc="ngbAccordion" activeIds="ngb-panel-0" class="accordianheading">
<ngb-panel>
<ng-template ngbPanelTitle>
<span>{{opt.description}}</span>
<button class='btn btn-sm btn-outline-primary btnline pull-right' (click)='$event.preventDefault(); $event.stopPropagation(); editItem(content, opt)'>Edit</button>
</ng-template>
<ng-template ngbPanelContent>
<js-option-lists [OptionListID]=opt.id></js-option-lists>
</ng-template>
</ngb-panel>
</ngb-accordion>
</div>
</div>
and:
.ts file
import { Component, OnInit, Input } from '#angular/core';
import { IOptionListHeader } from '../dtos/option-list-header';
import { OptionListService } from '../services/felixApi/option-list.service';
import { NgbModal, ModalDismissReasons } from '#ng-bootstrap/ng-bootstrap';
import { NgModel, NgForm } from '#angular/forms';
#Component({
selector: 'js-option-lists',
templateUrl: './option-lists.component.html',
styleUrls: ['./option-lists.component.css']
})
export class OptionListsComponent implements OnInit {
#Input() OptionListID: number;
errorMessage: any;
optionList: IOptionListHeader[] = [];
updatedOption: any;
closeResult: string;
editOption = '';
constructor(private _optionListService: OptionListService, private modalService: NgbModal) { }
// for now read in all options but will need to read by level
ngOnInit() {
this.getChildren(this.OptionListID);
}
getChildren (id) {
this._optionListService.getOptionListChildren(id)
.subscribe(
optionList => {
this.optionList = optionList;
},
error => this.errorMessage = <any>error);
}
// Patch change
patchOrderNo(updatedOption: any) {
this._optionListService.updateOption(updatedOption).subscribe(
res => {
this.getChildren(this.OptionListID);
},
err => {
console.log('error code ' + err.status);
}
);
}
editItem(content, opt: IOptionListHeader) {
this.editOption = opt.description;
this.modalService.open(content).result.then((result) => {
this.closeResult = `Closed with: ${result}`;
this.updatedOption = { id: opt.id, description: this.editOption };
this.patchOrderNo(this.updatedOption);
}, (reason) => {
this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;
console.log('cancelled');
});
}
private getDismissReason(reason: any): string {
if (reason === ModalDismissReasons.ESC) {
return 'by pressing ESC';
} else if (reason === ModalDismissReasons.BACKDROP_CLICK) {
return 'by clicking on a backdrop';
} else {
return `with: ${reason}`;
}
}
}
I'm new in angular2 and typescript and already spent a half day to figure out with ng2 forms. I have finished all my routes and builded all necessary form and currently trying to understand how to post in angular2 with typescript
This my error:
ERROR in [default]
simpleapp/src/app/clients/add-client/add-client.component.ts:52:16
Property 'http' does not exist on type 'AddClientComponent'.
And I cannot find where is this problem coming from. I've imported angular/http in my component, I have provided header and response as oficial tutorial says but still can see this problem. What am I missing and where is my problem? thanks in advance
This is my component:
import 'rxjs/add/operator/map';
import {Component} from '#angular/core';
import {Http, Response, RequestOptions, Headers} from '#angular/http';
import {Employee} from "./model/add-client.model";
#Component({
selector: 'app-add-client',
templateUrl: 'add-client.component.html',
styleUrls: ['add-client.component.css']
})
export class AddClientComponent {
departments: Array<any>;
firstName: '';
lastName: '';
id: null;
salary: null;
phone: null;
departmentId: null;
constructor(http: Http) {
http.get('api/departments')
.map((res: Response) => res.json())
.subscribe((departments: Array<any>) => this.departments = departments);
}
model = new Employee(
this.id,
this.firstName,
this.lastName,
this.salary,
this.departmentId,
this.phone
);
submitted = false;
addEmployee = 'api/employees'
handleError = 'Post Error';
onSubmit(model) {
this.submitted = true;
let body = JSON.stringify({ model });
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.post(this.addEmployee, body, options)
.catch(this.handleError);
}
}
This is my template:
<div class="container">
<md-card class="demo-card demo-basic">
<md-card-title color="primary back-header">Employee Form</md-card-title>
<md-card-content>
<form (ngSubmit)="onSubmit(model)" #employeeForm="ngForm">
<md-toolbar for="firstName">First Name</md-toolbar>
<md-input
class="demo-full-width input-text"
type="text"
id="firstName"
required
[(ngModel)]="model.firstName"
name="firstName"
#firstName="ngModel">
</md-input>
<md-toolbar for="lastName">Last Name</md-toolbar>
<md-input
class="demo-full-width input-text"
type="text"
id="lastName"
required
[(ngModel)]="model.lastName"
name="lastName"
#lastName="ngModel">
</md-input>
<md-toolbar for="salary">Salary</md-toolbar>
<md-input
class="demo-full-width input-text"
type="number"
id="salary"
placeholder="USD"
required
[(ngModel)]="model.salary"
name="salary"
#salary="ngModel">
</md-input>
<md-toolbar for="departmentId">Department</md-toolbar>
<select class="demo-full-width option-department input-text"
id="departmentId"
required
[(ngModel)]="model.departmentId"
name="departmentId"
#departmentId="ngModel">
<option
*ngFor="let department of departments"
[value]="department.id">{{department.name}}
</option>
</select>
<md-toolbar for="phone">Phone</md-toolbar>
<md-input
class="demo-full-width input-text"
type="number"
id="phone"
placeholder="phone #"
required
[(ngModel)]="model.phone"
name="phone"
#phone="ngModel">
</md-input>
<button md-raised-button color="primary"
type="submit"
class="btn btn-default"
[disabled]="!employeeForm.form.valid">Submit
</button>
</form>
</md-card-content>
</md-card>
<md-card [hidden]="!submitted">
<md-card-title>You submitted the following:</md-card-title>
<md-list>
<md-list-item>
<label>First Name:</label> {{model.firstName}}
</md-list-item>
<md-list-item>
<label>Last Name:</label> {{model.lastName}}
</md-list-item>
<md-list-item>
<label>Salary:</label> {{model.salary}}
</md-list-item>
<md-list-item>
<label>Department:</label> {{model.departmentId}}
</md-list-item>
<md-list-item>
<label>Phone:</label> {{model.phone}}
</md-list-item>
</md-list>
</md-card>
</div>
This is my module:
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { FormsModule } from '#angular/forms';
import { HttpModule } from '#angular/http';
import { MaterialModule } from '#angular/material';
import {MdListModule} from '#angular/material/list';
import { AppComponent } from './app.component';
import { routing, appRoutingProviders } from './app.routing';
//==============
import { ClientsComponent } from './clients/clients.component';
import { DepartmentsComponent } from './departments/departments.component';
import { AddClientComponent } from './clients/add-client/add-client.component';
import { AddDepartmentComponent } from './departments/add-department/add-department.component';
#NgModule({
imports: [
BrowserModule,
FormsModule,
HttpModule,
routing,
MaterialModule.forRoot(),
MdListModule.forRoot()
],
declarations: [
AppComponent,
ClientsComponent,
DepartmentsComponent,
AddClientComponent,
AddDepartmentComponent
],
providers: [appRoutingProviders],
bootstrap: [AppComponent]
})
export class AppModule { }
Just add private to make your Http instance available to your entire component:
constructor(private http: Http)
It has something to do with your http variable try this
In your component.ts
constructor(http: Http) {
http.get('api/departments')
.map((res: Response) => res.json())
.subscribe((departments: Array<any>) => this.departments = departments);
}
You could try
constructor(private http: Http) {
http.get('api/departments')
.map((res: Response) => res.json())
.subscribe((departments: Array<any>) => this.departments = departments);
}
You have to export the Http module in the module in the exports declaration.
#NgModule({
imports: [CommonModule, RouterModule, ReactiveFormsModule, ],
declarations: [ ErrorMessagesComponent, FoodDashboardComponent ],
exports: [ CommonModule, ReactiveFormsModule, HttpModule, RouterModule, ]
})
Issue error TS2339: Property 'http' does not exist on type 'FoodListComponent' solved by making http as private in constructor constructor(private http: Http) {
this.http = http;
}
I have a angular2 version debounce input control, template like below.
<input type="text" [ngFormControl]="compInput" placeholder="demo input" />
In my component.ts
import {Component} from "angular2/core";
import {Control} from "angular2/common";
#Component({
...
)
export class Demo{
private compInput = new Control();
constructor(){
this.compInput.valueChanges.subscribe(() => {});
}
}
these code works until I upgrade my angular2 version to latest.
It seems form usage has changed.
I changed [ngFormControl] to ngControl and Control to FormControl from "#angular/forms", but doesn't work.
Does anyone know where I am wrong about the new usage and how to fix?
Here's a simple example using ngModel
import {Component, Input, Output, HostListener, EventEmitter, ChangeDetectionStrategy} from '#angular/core';
import {Observable} from 'rxjs/Observable';
import {Subject} from 'rxjs/Subject';
#Component({
moduleId: module.id,
selector: 'user-search',
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<form role="search">
<div class="form-group">
<input
class="form-control"
name="input"
type="text"
placeholder="Search user"
[(ngModel)]="input"
(keyup)="keyup$.next($event.target.value)"
/>
</div>
</form>
`
})
export class UserSearchComponent {
input: string;
keyup$ = new Subject<string>();
#HostListener('window:keyup', ['$event'])
cancelSearch(event) {
if (event.code === 'Escape') {
this.input = undefined;
this.keyup$.next(undefined);
}
}
#Output() search: Observable<string> = this.keyup$
.debounceTime(700)
.distinctUntilChanged();
}
Thanks for all your help. I have find the answer for my question with help of my colleague. Here it is.
template.html
<form #form="ngForm">
<input name="nameInput" [(ngModel)]="componentName" #nameInput="ngModel">
</form>
component.ts
import {Component, ViewChild} from "#angular/core";
import {NgModel} from "#angular/common";
#Component({...})
export class Demo{
#ViewChild('nameInput') nameInput:NgModel;
componentName:string;
ngAfterViewInit(){
this.nameInput.update //or this.nameInput.control.valueChanges
.subscribe((val:any) => {console.log("value update", val);})
}
}