How to set formgroup data from angular - html

I have a formgroup like below:
this.myform = this.fb.group({
mydata: ''
});
I was able to set the data with formgroup setValue but in rendering the values in HTML, the option was not selected.
This is the HTML:
<div *ngFor="let item of (items$ | async); index as i; first as first">
<input type="radio" id="{{item.itemId}}" name="test" value="{{item.itemId}}" [formControl]="myform.controls.mydata"
selected = "(items$ | async).length ===1">
</div>
This doesnot select the first input label in HTML but in typescript the form is valid .

Use the setValue() method to set a new value for an individual control. The setValue() method strictly adheres to the structure of the form group and replaces the entire value for the control.
this.myform.setValue({ mydata: 'yourData' });

use the patchValue to set the value for the whole form
this.myform .patchValue({ mydata: 'yourData' });

Related

How to get multiple dynamic drop-down option values in one single list in Angular 7

I am creating a dynamic multiple dropdown in angualar 8. I am receiving list of list from backend and I am running through the list of list to generate multiple dynamic dropdown. Now I need to send selected option values from all the dropdown to backend again in Angular 8. I am unable to send all the value.
I am getting list in this format from which I am looping through to generate dynamic drop-down
cat_dropdown = [['A','B','C'],['1','2','3']]
Based on above list my html code generate two drop-downs one with options A,B,C and another with 1,2,3.
My HTML Code:
<form (ngSubmit)="segmentSelection()" #ff="ngForm">
<div id="userSelection" ngModelGroup="userData" #userData="ngModelGroup">
<div *ngFor="let first of cat_dropdown">
<mat-form-field>
<mat-label>Choose Segment Key</mat-label>
<mat-select id="selectme" name="segmentKey">
<mat-option *ngFor="let segment of first" [value]="segment">
{{segment}}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</form>
My component.ts code:
import { NgForm } from '#angular/forms';
export class myComponent implements OnInit {
#ViewChild("ff", { static: true }) segmentData: NgForm;
plotselection = {
segmentKey: []
}
segmentSelection(){
this.plotselection.segmentKey = this.segmentData.value.userData.segmentKey;
fetch("http://localhost:5000/data-decomposition", {
method: "POST",
headers: {
"Content-Type": "application/json"
},body: JSON.stringify({
segmentKey: this.segmentData.value.userData.segmentKey,
})
}).then(res => res.json()).then(myjson => {
console.log(myjson)
})
}
Now in my .ts component I have a dictionary name "plotselection" where I have key name 'segmentKey' which I defined as empty list.
As I have 2 dropdown in frontend so thought that i will receive two values from frontend and I will send those as a list to backend. When I select option from both the dropdowns for example from 1st dropdown I choose 'B' and from 2nd '3' and submit my selection, then when I console log the response I could only see the value '3' in my list not 'B' and '3' together. How can I have both the value to the list.
Thank you, and looking for your suggestion...
For my easiness I have used Select control instead of mat-select control.
In the form I have given specific name by appending the index to control while looping.
Html
<div *ngFor="let first of cat_dropdown; let num = index">
<div>
<Label>Choose Segment Key</Label>
<Select id="selectme{{num}}" [value]="segment" name="segmentKey{{num}}" (change)="ChangeCall($event.target)">
<option *ngFor="let segment of first" >
{{segment}}
</option>
</Select>
</div>
</div>
So that there are two controls with respective selected values.
There is also alternate solution is use to Change event on the Select Control.

How to set dropdown value in angular 7

I am trying to set dropdown value by programmatically using formcontrolname but not working.I have given my code below.How to set dropdown value that?Anyone can have idea?please help to find the solution.
app.component.html:
<p-dropdown [values]="dropdownData" fornControlName="datavalue"><p-dropdown>
app.component.ts:
dropdownData=[
{name:'UK',value:'UK'},
{name:'USA',value:'USA'},
{name:'CHINAA',value:'CHINAA'}
];
this.myform=this.fb.group({
datavalue:[null]
});
ngOnInit(){
this.myform.controls['datavalue'].setValue("USA");
}
This could work if you changed setValue as follows.
this.myform.controls['datavalue'].setValue(dropdownData[0]);
You should however inverse the logic and address the model from within your template using ngModel.
app.component.html:
<p-dropdown [values]="dropdownData" [(ngModel)]="selectedData"><p-dropdown>
app.component.ts:
dropdownData = [
{name:'UK',value:'UK'},
{name:'USA',value:'USA'},
{name:'CHINAA',value:'CHINAA'}
];
selectedData = dropdownData[0];
Please set the value like below in your app.component.ts:
this.myform.controls['datavalue'].setValue("USA", { onlySelf: true });
Also, please change the code in app.component.html like below:-
<p-dropdown [options]="dropdownData" fornControlName="datavalue"><p-dropdown>
Hope this helps you.

Working with custom components for input generates "No value accessor for form control with path X->0->Y"

I have a working form taking the following HTML markup. No errors or warnings.
<div class="input-element">
<div class="input-caption">Title</div>
<input type="text"
formControlName="targetField"
class="form-control">
</div>
I transformed it into a custom component, which also works, as shown below.
<app-input-text [info]="'Title'"
formControlName="targetField"
ngDefaultControl></app-input-text>
In my next view, I need to use FormArray as follows - still working code.
<div formArrayName="stuff">
<div *ngFor="let thing of form.controls.stuff.controls; let i = index;"
[formGroupName]=i>
<div class="input-element">
<div class="input-caption">Title</div>
<input type="text"
formControlName="targetField"
class="form-control">
</div>
</div>
</div>
Now, I expected that combining both (i.e. being able to use custom input component and being able to form array for components) would post no problem. However, the sample below doesn't work.
<div formArrayName="stuff">
<div *ngFor="let thing of form.controls.stuff.controls; let i = index;"
[formGroupName]=i>
<app-input-text [info]="'Title'"
formControlName="targetField"
class="col-sm-6"></app-input-text>
</div>
</div>
It generates the following error.
No value accessor for form control with path: 'stuff -> 0 -> targetField'
The custom component is design like this (although given that it works in the explicit markup example, I'm not sure if it's relevant information). The only (wild) guess I have might be that value isn't jacked into the form array field somehow.
export class InputTextComponent implements OnInit {
constructor() { this.value = new EventEmitter<string>(); }
#Input() info: string;
#Output() value: EventEmitter<string>;
onEdit(value: any): void { this.value.emit(value); }
}
The group and array creating in the current view is done like this (not sure if this is of any relevance neither, as it works for the explicit HTML markup case).
this.form = builder.group({
id: "",
stuff: builder.array([
builder.group({ targetField: "aaa" }),
builder.group({ targetField: "bbbb" }),
builder.group({ targetField: "cc" })
])
});
Is there a limitation in Angular in this regard that I'm not aware of? I'm rather sure there's not and that I'm just doing something fairly clever simply missing a tiny detail.
I do understand the error but I can't see how it relates to the code. The form can't find the 0th element in the array or that element has no field of that name. Since I do get to see a few rows, I know there must be a 0th element. Since I specified the name of the field, I know there is indeed such. What else am I missing?

Angular 2 Date Input not binding to date value

trying to get a form set up but for some reason, the Date input in my html is not binding to the object's date value, despite using [(ngModel)]
html:
<input type='date' #myDate [(ngModel)]='demoUser.date'/><br>
form component:
export class FormComponent {
demoUser = new User(0, '', '', '', '', new Date(), '', 0, [], []);
}
User class:
export class User {
constructor (
public id: number,
public email: string,
public password: string,
public firstName: string,
public lastName: string,
public date: Date,
public gender: string,
public weight: number,
public dietRestrictions: string[],
public fitnessGoals: string[]
){
}
}
A test output reveals the current "new" Date as the object's value, but the input doesn't update the User object's date value or reflect the value, suggesting neither of the two-way bindings are working. Help would be greatly appreciated.
Angular 2 , 4 and 5 :
the simplest way : plunker
<input type="date" [ngModel] ="dt | date:'yyyy-MM-dd'" (ngModelChange)="dt = $event">
Instead of [(ngModel)] you can use:
// view
<input type="date" #myDate [value]="demoUser.date | date:'yyyy-MM-dd'" (input)="demoUser.date=parseDate($event.target.value)" />
// controller
parseDate(dateString: string): Date {
if (dateString) {
return new Date(dateString);
}
return null;
}
You can also choose not to use parseDate function. In this case the date will be saved as string format like "2016-10-06" instead of Date type (I haven't tried whether this has negative consequences when manipulating the data or saving to database for example).
In your component
let today: string;
ngOnInit() {
this.today = new Date().toISOString().split('T')[0];
}
and in your html file
<input name="date" [(ngModel)]="today" type="date" required>
In .ts :
today: Date;
constructor() {
this.today =new Date();
}
.html:
<input type="date"
[ngModel]="today | date:'yyyy-MM-dd'"
(ngModelChange)="today = $event"
name="dt"
class="form-control form-control-rounded" #searchDate
>
use DatePipe
> // ts file
import { DatePipe } from '#angular/common';
#Component({
....
providers:[DatePipe]
})
export class FormComponent {
constructor(private datePipe : DatePipe){}
demoUser = new User(0, '', '', '', '', this.datePipe.transform(new Date(), 'yyyy-MM-dd'), '', 0, [], []);
}
Angular 2 completely ignores type=date. If you change type to text you'll see that your input has two-way binding.
<input type='text' #myDate [(ngModel)]='demoUser.date'/><br>
Here is pretty bad advise with better one to follow:
My project originally used jQuery. So, I'm using jQuery datepicker for now, hoping that angular team will fix the original issue. Also it's a better replacement because it has cross-browser support. FYI, input=date doesn't work in Firefox.
Good advise: There are few pretty good Angular2 datepickers:
https://github.com/emirdeliz/meus-projetos/tree/master/angular2-schedule/app/frontend/components/datepicker
https://github.com/MrPardeep/Angular2-DatePicker
https://www.npmjs.com/package/ng2-datepicker
As per HTML5, you can use
input type="datetime-local"
instead of
input type="date".
It will allow the [(ngModel)] directive to read and write value from input control.
Note: If the date string contains 'Z' then to implement above solution, you need to trim the 'Z' character from date.
For more details, please go through this link on mozilla docs.
If you are using a modern browser there's a simple solution.
First, attach a template variable to the input.
<input type="date" #date />
Then pass the variable into your receiving method.
<button (click)="submit(date)"></button>
In your controller just accept the parameter as type HTMLInputElement
and use the method valueAsDate on the HTMLInputElement.
submit(date: HTMLInputElement){
console.log(date.valueAsDate);
}
You can then manipulate the date anyway you would a normal date.
You can also set the value of your <input [value]= "..."> as you
would normally.
Personally, as someone trying to stay true to the unidirectional data flow, i try to stay away from two way data binding in my components.
you can use a workaround, like this:
<input type='date' (keyup)="0" #myDate [(ngModel)]='demoUser.date'/><br>
on your component :
#Input public date: Date,
In Typescript - app.component.ts file
export class AppComponent implements OnInit {
currentDate = new Date();
}
In HTML Input field
<input id="form21_1" type="text" tabindex="28" title="DATE" [ngModel]="currentDate | date:'MM/dd/yyyy'" />
It will display the current date inside the input field.

Accessing Object properties, from HTML Select.

Scenario:
I am trying to access a property (code) of a ng-Model object (myRide).
I've tried doing this by
<select ng-model = "myRide"
ng-change = "getCode(myRide.code)">
...and at getCode,
alert(parameter) //which should be myRide.code.
I've also tried to do this by
<select ng-model = "myRide"
ng-change = getCode(myRide)
(Note: 'myRide' is passed, not 'myRide.code') ...and at getCode,
alert(myRide.code).
myRide does indeed contain a property called 'code', which is not undefined.
Problem: Both tries do not produce the wanted outcome.
How can I make it display the property (code)?
Here is the JSFiddle: http://jsfiddle.net/a2J6z/1/
The better way to do this is to restructure the view. Instead of using ng-repeat on options inside of a select, use the ng-options directive. Then, you can bind the actual object to the model instead of just a JSON string, which is what your current fiddle is doing.
Your new select looks like
<select ng-options="car.Name for car in myGarage" ng-model="myRide" ng-change="getCode(myRide)">
</select>
Then in your controller
$scope.getCode = function(car){
alert(car.code);
}
An updated fiddle:
http://jsfiddle.net/a2J6z/5/
I updated the fiddle:
http://jsfiddle.net/a2J6z/3/
var ngApp = angular.module('ngAppl',[]);
function aControlla($scope){
$scope.myRide = "bus";
$scope.getCode = function(car){
alert(JSON.parse(car).code);
}
$scope.myGarage = [
{Name: "Toyota 86", code:"1"},
{Name: "Hyundai Genesis Coupe", code:"2"},
{Name: "Nissan GTR", code:"3"},
{Name: "Veyron", code:"4"}
];
};
And
<div ng-app="ngAppl">
<div ng-controller="aControlla">
<select ng-model="myRide" ng-change="getCode(myRide)">
<option ng-repeat="car in myGarage">{{car}}</option>
<!--Note: value of myRide MUST be simply 'car' (not say, 'car.Code')-->
</select>
<br/> This shows that 'myRide' contains the property called 'Name', and importantly, 'code':<br/> {{myRide}}
</div>
</div>
Basically I just had it alert what car was with myRide as the parameter, it showed the JSON string so I added the parse to get it to give me the code. There may be a better way I'm an AngularJS noob so to speak.