Angular 2 bind HTML inputs to component variables like in Vue? - javascript

So I've been struggling with this for a long time...I've been looking into the docs, but there are so many different directives and ways to communicate between components and the DOM, but only a few good examples...
So I'm actually not even sure what I need. Let's say I have a user input in my tables.component.html file like this:
<label>Name</label>
<input id="customerName" class="form-control" required>
Then there is my tables.component.ts file which looks like this:
import { Component, OnInit } from '#angular/core';
import { isLoggedIn } from '../../assets/js/auth.js';
import { Router } from '#angular/router';
#Component({
selector: 'app-tables',
templateUrl: './tables.component.html',
styleUrls: ['./tables.component.css']
})
export class TablesComponent implements OnInit {
customers = [];
id = ""; // keep outside of object to prevent user changes
customer_form = {
name: "",
job: "",
address: "",
birthdate: "",
email: "",
}
constructor(private router: Router) { }
...
}
To make it simple: I want to bind the user input above to the customer_form.name variable in my component. I'm looking for the equivalent of Vue 2.0 models, so that if the user changes the input value, the component value changes aswell. I don't neccessarily have to push the data within a form since we've got the task not to set up any backend...
Anyway, I'm kinda confused. I read the docs, but that made it just worse. One page says I'm supposed to add a controller to the form and add a script to the bottom of the HTML, another one said I have to make a template of the form that should be stored in the component...And then there are so many different directives to bind things. I was assuming you'd want to use ngModel for that, but I couldn't seem to get that working like in the examples I found.
Thanks for any help in advance..

I have created a simple example of binding in a template-driven form: https://stackblitz.com/edit/angular-m2tkrf
Note that FormsModule is imported in app.module.ts
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { FormsModule } from '#angular/forms'; //<---- IMPORTED
import { AppComponent } from './app.component';
import { HeroFormComponent } from './hero-form/hero-form.component';
#NgModule({
imports: [
BrowserModule,
FormsModule //<---- IMPORTED IN MODULE
],
declarations: [
AppComponent,
HeroFormComponent
],
providers: [],
bootstrap: [ AppComponent ]
})
export class AppModule { }

I think what you're looking for is [(ngModel)] which is used for two-way data binding.
<input
id="customerName"
class="form-control"
required
[(ngModel)]="customer_form.name"
name="name">
PS: To use the [(ngModel)], you'll have to import FormsModule and then add it the the imports array of your AppModule or whatever module you're using it in.
...
import { FormsModule } from '#angular/forms';
...
#NgModule({
imports: [
...,
FormsModule,
...
],
...
})
export class AppModule { }

Use ngModel for two-way data binding
put [(ngModel)] on the input to pass the data from & to your property like this:
//app.module code
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { FormsModule } from '#angular/forms'; //<---- IMPORTED
import { AppComponent } from './app.component';
import { TablesComponent } from './tables.component'; //<---- IMPORTED
#NgModule({
imports: [
BrowserModule,
FormsModule //<---- IMPORTED IN MODULE
],
declarations: [
AppComponent,
TablesComponent //<---- IMPORTED
],
providers: [],
bootstrap: [ AppComponent ]
})
export class AppModule { }
//--------------------------tables.component.html
<input id="customerName" class="form-control" [(ngModel)]="customer_form.name" required>

Related

Angular formControl fails to load

I'm following Angular tutorial on forms here:
https://angular.io/guide/reactive-forms
I have this code in 'datasources.component.html':
<form [formGroup]="queryForm">
<label>Query:
<input type="text" formControlName="query">
</label>
And this in 'datasources.component.ts':
import { Component } from '#angular/core';
import { FormGroup, FormControl } from '#angular/forms';
#Component({
selector: 'sql-editor',
templateUrl: './datasources.component.html',
styleUrls: ['./datasources.component.scss']
})
export class DatasourcesComponent {
queryForm = new FormGroup({
query: new FormControl(''),
});
}
I see its stuck at 'websocket : pending'
Also, my original intent is to make it work for 'textarea'. Is the solution going to work for that too?
<textarea class="form-control" rows="5" id="sql-query" [formControl]="query"></textarea>-
I'm using Angular version 7.2:
EDIT:
I see this error in console 'Can't bind to 'formGroup' since it isn't a known property of 'form'
Import ReactiveFormsModule in your AppModule
import { ReactiveFormsModule } from '#angular/forms';
#NgModule({
imports: [
// other imports ...
ReactiveFormsModule
],
})
export class AppModule { }
formGroup, formControl, etc are all directives that are exposed as a part of the ReactiveFormsModule.
If you want to use these directives in a Component, you'll have to either import the ReactiveFormsModule in the Module that this Component is registered in. Or you'll have to export the ReactiveFormsModule from some other module(SharedModule for instance) and then import that module in the module that you have this Component registered in.
import { ReactiveFormsModule } from '#angular/forms';
#NgModule({
imports: [
// other imports ...
ReactiveFormsModule
],
})
export class YourComponentModule { }
Also use the formcontrols like shown below:
<textarea class="form-control" rows="5" id="sql-query" formControlName="query"></textarea>

HelloComponent is not part of NgModule even though it's listed in the entry components?

I've created a stackblitz where I'm trying to instantiate the HelloComponent dynamically using the ReflexiveInjector and I have the HelloComponent listed in the app modules entryComponents array.
However I'm still getting:
Component HelloComponent is not part of any NgModule or the module has not been imported into your module.
Thoughts?
Added a link to this SO in this feature request asking for virtual / logical modules. Please thumbs it up if you like the suggestion.
You should also declare the HelloComponent in your declarations array of your module. Read the official docs about entrycomponents.
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { FormsModule } from '#angular/forms';
import { AppComponent } from './app.component';
import { HelloComponent } from './hello.component';
#NgModule({
imports: [ BrowserModule, FormsModule ],
entryComponents: [HelloComponent],
declarations: [ AppComponent, HelloComponent ], // declare here
bootstrap: [ AppComponent ]
})
export class AppModule { }

Angular 7 with adding new component 'the server component' isn't appear in browser when I add a component tag?

It is first time To use Angular Now I'm learning angular 7:
- I create a new custom component in
- |src folder
---| app
----|| server (name of my component)
then I added in app.component.html the name of component
I see in the tutorial show in browser
the server component
even if he add it empty element
I do all steps in
server.component.ts file
import { Component } from '#angular/core';
#Component({
selector:'app-server',
templateUrl: './server.component.html'
})
export class ServerComponent {
}
& app.module.ts file
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppComponent } from './app.component';
import { ServerComponent } from './server/server.component';
#NgModule({
declarations: [
AppComponent,
ServerComponent
],
imports: [
BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Have you define your <app-server></app-server> somewhere?
For instance in the app.component.html
<app-navbar></app-navbar>
<app-server></app-server>
<app-footer></app-footer>
Also you will find an example here : https://angular.io/tutorial/toh-pt1
In your app.component.html add :
<app-server></app-server>
Thus you'll see its HTML.
What you did is in fact kind of import it and make it visible to other components declared in AppModule, but you didnt call it actually.

Bootstrapping multiple module in Angular 6 via array

is it possible to declare an array and use that to bootstrap multiple components in module.ts.
I was trying something like this
export var initialComponents = [];
initialComponents.push(AppComponent);
if(condition) {
initialComponents.push(IchFooterComponent);
}
and then
bootstrap: initialComponents
Which gives me the following error
Error: The module oa was bootstrapped, but it does not declare "#NgModule.bootstrap" components nor a "ngDoBootstrap" method. Please define one of these.
You can customize the bootstrapping via implementing ngDoBootstrap as method of AppModule.
You can list your components which need to be bootstrapped in the entryComponents property of #NgModule
#NgModule({
entryComponents: [AComponent, BComponent, ...]
...
})
export class AppModule {
constructor() {}
ngDoBootstrap(appRef: ApplicationRef) {
if (Math.random() > 0.5) {
appRef.bootstrap(AComponent, '#app');
} else {
appRef.bootstrap(BComponent, '#app');
}
}
If you need a service, you can access them via dependency injection (put it in AppModule as constructor parameter). But I don't know if there are any limitations to it compared to DI in components or services.
Here are the docs for ApplicationRef and its bootstrap method.
Try it again (below is the sample code):
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { FormsModule } from '#angular/forms'; // <-- NgModel lives here
import { AppComponent } from './app.component';
import { HeroesComponent } from './heroes/heroes.component';
var initialComponents: any[] = [];
initialComponents.push(AppComponent);
if (true) {
initialComponents.push(HeroesComponent);
}
#NgModule({
declarations: initialComponents,
imports: [
BrowserModule,
FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Try this again:
https://stackblitz.com/edit/angular-vimqb1?file=src/app/app.module.ts

Directive not working in application

I can't figure out how to get directives working in my app. I want to apply a directive to a component, this is it in it's simplest form.
import {Directive, HostBinding} from '#angular/core';
#Directive({
selector: '[directiveSelector]'
})
export class FirstDirective {
#HostBinding() innerText = 'not working';
}
...
import {Component} from '#angular/core';
#Component({
selector: 'home',
template: `
<h1 directiveSelector>Test</h1>`
})
export class HomeComponent {
}
...
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppComponent } from './app.component';
import { HomeModule } from "./home/home.module";
import { FirstDirective } from './directives/first.directive';
#NgModule({
imports: [
BrowserModule,
HomeModule
],
declarations: [
AppComponent,
FirstDirective
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Does anyone know what I am missing here? Home renders fine, and is a component wrapped in a module. Also, I cannot get a debugger or alert to fire off in the directive - may be a problem with the template binding?
Declare the FirstDirective in your HomeModule, that should take care of it. Here I assume that your HomeComponent is part of homemodule.
Tried leaving it out myself from a module, and it produced no error but also didn't work.

Categories

Resources