Angular2 Select 2-Way Binding not updating - html

so im trying to Bind the selected Item of a Dropdown to a Property with 2 way binding but the property in my typescript code always stays the same.
This is my Select Tag:
<select #select class="form-control" id="favouriteValue" ([ngModel])="selectedValue">
<option *ngFor="let value of valuesFromHomeComp" [ngValue]="value">{{value.name}}</option>
</select>
this is my component:
import { Component, OnInit, Input } from '#angular/core';
#Component({
selector: 'app-register',
templateUrl: './register.component.html',
styleUrls: ['./register.component.css']
})
export class RegisterComponent implements OnInit {
model: any = {};
#Input()valuesFromHomeComp: any[];
selectedValue: any;
constructor() {}
ngOnInit() {
this.selectedValue = this.valuesFromHomeComp[0];
}
}

You're using the wrong syntax, it should be [(ngModel)] instead.
As a hint: Its bananas in a box. The square brackets enclose the "banana" brackets.

Related

How to get the selected value from one component to other using event emitter in angular 8

I have 2 components , one login and other home. When I change drop down into login component ,selected value need to display in home component. I am already emitting the onchange event from login component to home component and displaying the value but still I am not getting the value into home component.Here is the code below
login.component.html
<select #mySelect (change)="onOptionsSelected(mySelect.value)">
<option value="one">one</option>
<option value="two">two</option>
</select>
login.component.ts
import { Component, OnInit,Input,Output, EventEmitter } from '#angular/core';
import { Router } from '#angular/router';
#Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
#Output() buttonClicked = new EventEmitter();
constructor(private router: Router) { }
#Input() item: string;
ngOnInit() {
}
onOptionsSelected(value:string){
console.log("the selected value is " + value);
this.buttonClicked.emit(value);
this.router.navigateByUrl('/home');
}
}
home.component.html
<p>home works!</p>
<app-login (buttonClicked)='showNextComponent($event)'></app-login>
<p>Hello {{ name }} </p>
home.component.ts
import { Component, OnInit,ElementRef,ViewChild } from '#angular/core';
import { CommonserviceService } from './../utilities/services/commonservice.service';
import { LoginComponent } from '../login/login.component';
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
getListData: any;
constructor(private commonserviceService: CommonserviceService) { }
name:string
ngOnInit() {
}
showNextComponent(value:string) {
this.name = value;
console.log(this.name);
}
}
I pasted your code here in stackblitz: https://stackblitz.com/edit/angular-cfkqns
You are correctly emitted values up to the parent component and binding the value to be displayed in the parent component.
It is working how you expect it to :-)
UPDATE:
I have answered the same question for some one else here:
https://stackoverflow.com/a/64082745/450388
however I have updated your stackblitz to reflect how to achieve the same.
https://stackblitz.com/edit/angular-cfkqns

Cannot access the parent formControl object changes in a Parent-Child Component relationship in Angular 8

I have created a parent component as follows:
<form [formGroup] = "cardForm">
<app-inputvalidator [controls] = "cardForm.get('name')"></app-inputvalidator>
</form>
Parent ts file
import { Component, OnInit } from '#angular/core';
import { FormGroup, FormControl,Validators } from '#angular/forms';
#Component({
selector: 'app-card-form',
templateUrl: './card-form.component.html',
styleUrls: ['./card-form.component.css']
})
export class CardFormComponent implements OnInit {
nameFormControl ;
cardForm = new FormGroup({
name: new FormControl('', [Validators.minLength(5),Validators.maxLength(25)])
});
constructor() {
}
ngOnInit(): void {
this.nameFormControl = this.cardForm.get('name');
}
}
I am passing the nameFormControls to the child component and accessing it in the template as well as class as follows:
InputValidator.ts
import { Component, OnInit, Input } from '#angular/core';
import { FormControl} from '#angular/forms';
#Component({
selector: 'app-inputvalidator',
templateUrl: './inputvalidator.component.html',
styleUrls: ['./inputvalidator.component.css']
})
export class InputvalidatorComponent implements OnInit {
#Input() controls: FormControl;
constructor() {
}
ngOnInit(): void {
}
}
Input Validator.html
<input [formControlName] = "controls"
<br>
<div>{{ controls.errors | json}}</div>
The project is compiled successfully with no errors.
I am getting the value of controls.errors to always null.
Why can I not print the object controls.errors using string interpolation as the value in the name input box changes?
you get null becuase you don't put required validator the min,maxLength validators will return an error if there is value and the value is not valid , if the value is null or empty string this will consider a valid
check the validator 👉 source

How to get check particular checkboxes by default based on some values in angular 7

I have a checkboxes and selectbox whose values are coming from loop,but here I need to get some checkboxes checked by default based on an array of object.Here checkbox and selectbox value is coming from usersg and usersr variable.But the checked and selected by default should be from variable usersg_checked and usersr_selected inside ngOnInit(). Here is the code below
home.component.html
<p *ngFor="let group of usersg"><input type="checkbox" checked="checked.id" value="{{group.id}}" />{{group.name}}</p>
<p><select><option *ngFor="let role of usersr" value="{{role.id}}">{{role.name}}</option></select></p>
home.component.html
import { Component, OnInit } from '#angular/core';
import { CommonserviceService } from './../utilities/services/commonservice.service';
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
submitted = false;
usersg_checked:any;
usersr_selected:any;
constructor(private formBuilder: FormBuilder) {
}
public usersg = [{"id":1,"name":"test1"},{"id":2,"name":"test2"},{"id":3,"name":"test3"},{"id":4,"name":"test4"}];
public usersr = [{"id":1,"name":"test1"},{"id":2,"name":"test2"}];
ngOnInit() {
this.usersg_checked = [{"id":1,"name":"test1"},{"id":2,"name":"test2"}];
this.usersr_selected = [{"id":1,"name":"test1"}];
}
}
Add isChecked() method in component to check if a checkbox must be selected.
Component:
isChecked(id) {
return this.usersg_checked.some(item => item.id === id);
}
Template:
<p *ngFor="let group of usersg">
<input type="checkbox" [checked]="isChecked(group.id)" value="{{group.id}}" />{{group.name}}
</p>
For <select> elements better to use [(ngModel)].
Template:
<p><select [(ngModel)]="usersr_selected.id">
<option *ngFor="let role of usersr" value="{{role.id}}">{{role.name}}</option>
</select></p>
Component:
And change usersr_selected to an object.
ngOnInit() {
this.usersr_selected = {"id":1,"name":"test1"};
}
If usersr_selected is an array, use the first element of the array as NgModel.
ngOnInit() {
this.usersr_selected = this.usersr_selected[0];
}

How to get selected value of dropdown in angular 6 on load(not onchange)

I have a select dropdown ,I am getting option's data and value from an array through loop. Here I need to get the value of selected drop down when page loads without onchange(in this case Recent). Here is code below.
app.component.html
<select>
<option *ngFor="let v of values" [value]="v.id">
{{v.name}}
</option>
</select>
app.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{
title = 'projectchart';
public values = [
{ id: 3432, name: "Recent" },
{ id: 3442, name: "Most Popular" },
{ id: 3352, name: "Rating" }
];
ngOnInit(){
alert('The default selected value is');
}
}
you could make use of reactive forms
constructor(private fb: FormBuilder) { }
// create a form group using the form builder service
formName = this.fb.group({
name: ['']
})
in the template
<form [formGroup]="formName">
<select formControlName="name">
<option *ngFor="let v of values" [value]="v.id">
{{v.name}}
</option>
</select>
</>
and then get the value in the ts:
this.formName.controls['name'].value

Kind of recursive usage of an Component possible?

After searching for like two hours for a solution I decided to ask some pros suspecting the solution could be quite simple.
It is an Angular7 project.
I would like to have a "goal" in my goals component with a button "+". When you click that button I want to have annother goal being added to the page. So I want to click a button of the goal component to create a new goal, which is something like recursive to me.
goals.component.html:
<input type="text" value="Ich brauche einen Laptop für maximal 1000 Euro.">
<br/>
<br/>
<app-goal id="{{lastGivenId+1}}"></app-goal>
goals.component.ts:
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-goals',
templateUrl: './goals.component.html',
styleUrls: ['./goals.component.scss']
})
export class GoalsComponent implements OnInit {
lastGivenId: number = 0;
constructor() { }
ngOnInit() {
}
}
goal.component.ts and goal.component.html:
//Typescript code
import { Component, OnInit, Input } from '#angular/core';
#Component({
selector: 'app-goal',
templateUrl: './goal.component.html',
styleUrls: ['./goal.component.scss']
})
export class GoalComponent implements OnInit {
#Input() id : number;
constructor() { }
ngOnInit() {
}
onAddLowerGoal(currentGoalID:number){
// var goalElement = document.registerElement('app-goal');
// document.body.appendChild(new goalElement());
let newGoal = document.createElement("app-goal");
newGoal.setAttribute("id", "999");
let currentGoal = document.getElementById(currentGoalID.toString());
document.body.insertBefore(newGoal, currentGoal);
}
}
<html>
<div id="{{id}}" class="goal">goal{{id}}</div>
<button id="AddLowerGoal1" (click)="onAddLowerGoal(999)">+</button>
</html>
This way, it creates an app-goal element, but the div and button elements within the app-goal element is missing.
How can this problem be solved? Any help is welcome. Thanks in advance.
First glance: delete the html tags from your goal.component.html file.
Next: you can recursively add app-goal using angular. Inserting app-goal element the javascript way only adds the <app-goal></app-goal> object. It doesn't create an angular component. It doesn't bind your data.
Also if you're using Angular's #Input, you need to assign a component input with square braces. Do not use tags.
goals.component.html:
<input type="text" value="Ich brauche einen Laptop für maximal 1000 Euro.">
<br/>
<br/>
<app-goal [id]="lastGivenId+1"></app-goal>
goal.component.html:
<div id="{{id}}" class="goal">goal{{id}}</div>
<button id="AddLowerGoal1" (click)="onAddLowerGoal(999)">+</button>
<div *ngFor="let subGoal of subGoals">
<app-goal [id]="subGoal.id"></app-goal>
</div>
goal.component.ts:
import { Component, OnInit, Input } from '#angular/core';
#Component({
selector: 'app-goal',
templateUrl: './goal.component.html',
styleUrls: ['./goal.component.scss']
})
export class GoalComponent implements OnInit {
#Input() id : number;
subGoals: Array<any> = [];
constructor() { }
ngOnInit() { }
onAddLowerGoal(currentGoalID: number){
this.subGoals.push({id: currentGoalID});
}
}
You can also use a service to store your goals and subgoals to access them later.
I think what you're looking for is a Reactive Form with FormArray with dynamically added form controls.
Take a look at this for eg:
import { Component } from '#angular/core';
import { FormControl, FormGroup, FormArray, FormBuilder } from '#angular/forms';
#Component({...})
export class GoalsComponent {
goalsForm: FormGroup;
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.goalsForm = this.fb.group({
goals: this.fb.array([])
});
}
onFormSubmit() {
console.log('Form Value: ', this.goalsForm.value);
}
get goals() {
return (<FormArray>this.goalsForm.get('goals')).controls;
}
addGoal() {
(<FormArray>this.goalsForm.get('goals')).push(this.fb.control(null));
}
}
And here's the template for this:
<h2>Goals:</h2>
<form [formGroup]="goalsForm" (submit)="onFormSubmit()">
<button type="button" (click)="addGoal()">Add Goal</button>
<hr>
<div *ngFor="let goal of goals; let i = index;" formArrayName="goals">
<div>
<label for="goal">Goal {{ i + 1 }}: </label>
<input type="text" id="goal" [formControlName]="i">
</div>
<br>
</div>
<hr>
<button>Submit Form</button>
</form>
Here's a Sample StackBlitz for your ref.