It throws me this error in console, however the form is working right whenever I clic.
Seriously, I don't see the mistake, I have another template with the same syntax and it doesn't throw me this error
<div class="container-fluid">
<div class="row">
<div class="col-md-5">
<div class="card">
<div class="header">
<h4 class="title">Comparativa mensual</h4>
<p class="category">Año actual</p>
</div>
<div class="content">
<app-pie-graph #graphmonths></app-pie-graph>
</div>
</div>
</div>
<div class="col-md-7">
<div class="card ">
<div class="header">
<div class="formGroup">
<form [formGroup]="dataForm" (ngSubmit)="submit($event)">
<h4 class="title inline">Comparativa diaria</h4>
<my-date-range-picker name="mydaterange" [options]="myOptions" formControlName="myDateRange"></my-date-range-picker>
<button type="submit" class="btn btn-primary">Consultar</button>
</form>
</div>
<p class="category">Vista de una semana</p>
</div>
<div class="content">
<div class="row">
<div class="col-sm-8">
<app-pie-graph #graphdays></app-pie-graph>
</div>
</div>
</div>
</div>
</div>
</div>
Error
ERROR Error: formControlName must be used with a parent formGroup directive. You'll want to add a formGroup
directive and pass it an existing FormGroup instance (you can create one in your class).
Example:
<div [formGroup]="myGroup">
<input formControlName="firstName">
</div>
In your class:
this.myGroup = new FormGroup({
firstName: new FormControl()
});
UPDATE: ts file------------------------------------------------------------------------------------------------------------------------------------------------
import { Component, ViewChild, OnInit, AfterViewInit, QueryList } from '@angular/core';
import { LinearGraphComponent } from '../../shared/graph/linear-graph/linear-graph.component';
import { PieGraphComponent } from '../../shared/graph/pie-graph/pie-graph.component';
import { Validators, FormGroup, FormControl } from '@angular/forms'
import { Data } from '../data';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-overview',
templateUrl: './overview.component.html',
styleUrls: ['./overview.component.css']
})
export class OverviewComponent implements AfterViewInit, OnInit{
@ViewChild('graphdays') private pieGraphDays: PieGraphComponent;
@ViewChild('graphmonths') private pieGraphMonths: PieGraphComponent;
@ViewChild('generaloverview') private linearGraph: LinearGraphComponent;
//COMMON
public getDataRetriever(): Data { return this.dataRetriever; }
//COMMON
//private disableButton(){ this.blocked = true; }
//COMMON
//private activateButton(){ this.blocked = false; }
//COMMON VARIABLE
private userid = parseInt(this.route.parent.snapshot.params.id);
private dataForm = new FormGroup({
myDateRange: new FormControl(null, Validators.required)
});
constructor(
private dataRetriever: Data,
private route: ActivatedRoute
){
}
ngOnInit(){
}
private getMonthAgo(since: Date): Date{
var monthAgo = new Date(since.getTime());
monthAgo.setMonth(monthAgo.getMonth() - 3);
monthAgo.setHours(8, 0, 0, 0);
return monthAgo;
}
private displayLastMonthDaysLinear(){
var that = this;
var yesterday = this.getYesterday();
var monthAgo = this.getMonthAgo(yesterday);
this.getDataRetriever().getRangeDays(this.userid, monthAgo, yesterday, function(){
let data = that.getDataRetriever().getData();
let labels = that.getDataRetriever().getXLabels();
console.log(labels);
that.linearGraph.setChart(data, labels);
});
}
private displayLastWeekPie(){
var that = this;
var monday = this.getMondayCurrentWeek();
var yesterday = this.getYesterday();
if(monday.getDate() === new Date().getDate()) //If today is monday
monday.setDate(monday.getDate()-7); //Get monday from previous week
this.getDataRetriever().getRangeDays(this.userid, monday, yesterday, function(){
let data = that.getDataRetriever().getData();
let labels = that.getDataRetriever().getXLabels();
console.log(labels);
that.pieGraphDays.setChart(data[0].data, labels);
});
}
private displayLastMonthsPie(){
var now = new Date();
var newYear = new Date(now.getFullYear(), 0, 1, 8, 0, 0, 0);
var last = new Date(new Date().setMonth(now.getMonth()-1));
var that = this;
if(newYear.getMonth() === now.getMonth()) //If we are in January (spetial case)
newYear.setFullYear(newYear.getFullYear() - 1); //Get January from past year
this.getDataRetriever().getCountingPerMonth(this.userid, newYear, last, function(){
let data = that.getDataRetriever().getData();
let las = that.getDataRetriever().getXLabels();
console.log(data);
that.pieGraphMonths.setChart(data, las);
});
}
private getDaysToMonth(month, year): number[] { //month not included
var date = new Date(year, month, 1);
var days = [];
while (date.getMonth() < month) {
days.push(new Date(date).setHours(8,0,0,0));
date.setDate(date.getDate() + 1);
}
return days;
}
private getYesterday(): Date{
var today = new Date();
today.setDate(today.getDate() - 1);
today.setHours(8,0,0,0);
return today
}
private getMondayCurrentWeek(): Date{
var d = new Date();
var day = d.getDay(),
diff = d.getDate() - day + (day == 0 ? -6:1); // adjust when day is sunday
d.setDate(diff);
d.setHours(8,0,0,0);
return d;
}
ngAfterViewInit(){
this.displayLastMonthsPie();
this.displayLastWeekPie();
this.displayLastMonthDaysLinear();
console.log(this.linearGraph);
}
submit(){
let range = this.getPickedDayRange();
var that = this;
this.getDataRetriever().getRangeDays(this.userid, range[0], range[1], function(){
let data = that.getDataRetriever().getData();
let labels = that.getDataRetriever().getXLabels();
that.pieGraphDays.setChart(data[0].data, labels);
});
}
//COMMON CLASS
private getPickedDayRange(): Date[]{
var begDate = new Date(this.dataForm.value.myDateRange.beginJsDate);
var endDate = new Date(this.dataForm.value.myDateRange.endJsDate);
return [begDate, endDate];
}
}
I pieced together the answers from another post.
The short answer is that you have to declare the formGroup in the parent component, then pass in the formGroup to the child component.
app.component.ts
feedbackValues = [1,2,3,4,5];
constructor(private formBuilder: FormBuilder) {
this.surveyForm = this.formBuilder.group({
rowForm: this.formBuilder.group({
rating: ['']
})
});
app.component.html
<form [formGroup]="surveyForm" (ngSubmit)="onSubmit()" >
<app-survey-row [feedbackValues]=feedbackValues [parentGroup]="surveyForm"></app-survey-row>
<button type="submit">Submit</button>
</form>
survey-row.component.ts
export class SurveyRowComponent implements OnInit {
@Input() feedbackValues;
@Input() parentGroup: FormGroup;
constructor( private formBuilder: FormBuilder) {
}
ngOnInit() {
}
}
survey-row.component.html
<div [formGroup]="parentGroup">
<div formGroupName="rowForm">
<div *ngFor="let val of feedbackValues; let i = index">
<input id="{{i+1}}" type="radio" value="{{i+1}}" formControlName="rating">
<label for="{{i+1}}">{{i+1}}</label>
</div>
</div>
</div>
Notice how the [formGroup]
is passed in by the parent component, and the formGroupName
is not declared in survey-row, but in app.component.ts
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With