Problem with storing data in Firebase (_isScalar: false) - javascript

I have created a form that stores the course type data in the Firebase. When I try to save a new element it creates this: https://i.stack.imgur.com/jXO1z.jpg.
Here's my code in create-course Component:
form: FormGroup = this.fb.group({
name: [''],
code: [''],
ects: [''],
lekt: ['']
})
constructor(private fb: FormBuilder, private dataStorageService : DataStorageService) { }
ngOnInit(): void {}
onSaveData(){
this.dataStorageService.storeCourses();
}
Here's the code in the service component :
storeCourses(){
const courses = this.courseService.getCourses();
this.http.put(
'https://projekti-ff52b-default-rtdb.firebaseio.com/courses.json',
courses)
.subscribe(response => {
console.log(response);});
}
getCourses() {
return of(this.courses); }
private courses: Course[] = [];
And Course [] is an exported interface from course model.ts

Related

Add/ remove custom validators to form array in angular 8

Hi I am trying to set/ take away custom validators for different elements in a form array that can change around, so far what I have tried to do is create a switch statement and loop through all of the input types that are set so I could set the validation rule as well as send a message to the user if the rule isn't met. The problem I am having is the form is initialized before the form data is set.
So my question is how can I loop through the array and set the validation rules. If someone could let me know if im along the right tracks with using a switch statement but have code in the wrong place or if there is a different and better approach it would be most helpful thank you
export class ReactiveComponent implements OnInit {
public form: FormGroup;
public fieldList: any;
types: Array<any>;
formData: any;
Param: string;
setData: any;
formLabelNames: any;
get contactFormGroup() {
return this.form.get('inputs') as FormArray;
}
constructor(
private route: ActivatedRoute,
private fb: FormBuilder,
private api: FormService,
private notifiy: NotificationService,
private auth: AuthService,
private router: Router) { }
ngOnInit() {
this.form = this.fb.group({
name: ['', Validators.compose([Validators.required])],
organization: ['', Validators.compose([Validators.required])],
inputs: this.fb.array([this.createForm()])
});
this.route.paramMap.subscribe(params => {
this.Param = params.get('id');
this.getForm(this.Param);
});
// set fieldslist to this field
this.fieldList = this.form.get('inputs') as FormArray;
}
// formgroup
createForm(): FormGroup {
return this.fb.group({
type: ['', Validators.compose([Validators.required])],
name: ['', Validators.compose([Validators.required])],
value: ['', this.validators()]
});
}
getForm(id) {
this.api.getForm(id).subscribe(
(data: any) => this.setForm(data)
);
}
getFieldsFormGroup(index): FormGroup {
const formGroup = this.fieldList.controls[index] as FormGroup;
return formGroup;
}
getContactsFormGroup(index): FormGroup {
const formGroup = this.fieldList.controls[index] as FormGroup;
return formGroup;
}
setForm(data) {
const d = data.results;
this.setData = d;
this.formLabelNames = d[0].fields;
this.form.patchValue({
name: [d[0].form_name],
organization: [d[0].org],
});
this.form.setControl('inputs', this.setExistingFields(d[0].fields));
}
setExistingFields(fields: any): FormArray {
const formArray = new FormArray([]);
this.fieldList = formArray;
fields.forEach(f => {
formArray.push(this.fb.group({
name: f.name,
type: f.type,
value: f.value
}));
});
return formArray;
}
/* This is where I have tried to create a switch statement but I get a undefined error because the setform function is being called after this one */
validators() {
this.formLabelNames.type.forEach((field: any) => {
switch (field.type) {
case 'email':
}
});
}
submit() {
if (this.form.valid) {
const formId = this.Param;
const local = this.auth.decodePayload();
const userId = local.sub;
this.router.navigateByUrl('/dashboard');
this.api.sendForm(this.form.value, formId, userId).subscribe();
this.form.reset();
} else {
this.notifiy.showFailure('Form is not valid', 'Error');
}
}
}
You have several problems, as far as I can judge:
You don't initialize neither the formControls nor the formArray correctly inside of you formGroup. It should rather look like this:
this.form = this.fb.group({
name: new FormControl( "", {validators: [Validators.required]}),
organization: new FormControl( "", {validators: [Validators.required]}),
inputs: this.fb.array([new FormControl(), new FormControl()]),
});
Besides: What is the point of using a formArray when it consists of only one formGroup?
Off course you can set the validators for any abstractControl be it a formControl or a formGroup. For the array it would look like something like this:
this.formArray.controls.map((ctrl) => {
ctrl.setValidators([Validators.required, Validators.email]);
});
It doesn't matter where in the component class you put your method. Though it surely matters when that method is invoked!

MomentJS changing value when assigned to new variable

When I try assigning a moment to a new variable it changes the value without me modifying it.
I have tried everything from forcing the use of UTC and settings timezones. It just keeps changing the value.
#Component({
selector: 'app-appointment-create',
templateUrl: './appointment-create.component.html',
styleUrls: ['./appointment-create.component.css']
})
export class AppointmentCreateComponent implements OnInit {
appointment: CreateAppointmentDto;
form: FormGroup;
private formSubmitted: boolean;
tasks: Task[];
availability: Availability[];
task: number;
availablemoments: Moment[];
constructor(
private titleService: Title,
private router: Router,
private appointmentService: AppointmentService,
private taskService: TasksService,
private webLogger: WebloggerService,
private availabilityService: AvailabilityService,
) {
this.appointment = new CreateAppointmentDto();
}
dateFilter = (d: Moment): boolean => {
return this.availability.filter(s => s.timestampstart.isSame(d, 'day')).length >= 1;
}
ngOnInit() {
this.titleService.setTitle('New Appointment');
this.taskService.getActiveTasks().subscribe(value => {this.tasks = value; });
this.form = new FormGroup({
timestampstart: new FormControl(this.appointment.timestampstart, Validators.required),
daystart: new FormControl(this.appointment.timestampstart, Validators.required),
location: new FormControl(this.appointment.location, Validators.required),
description: new FormControl(this.appointment.description, Validators.required),
paid: new FormControl(false, Validators.required),
serviceType: new FormControl(this.appointment.serviceTypeId, Validators.required),
client: new FormControl(this.appointment.clientId, Validators.required),
assignedUser: new FormControl(this.appointment.assignedUserId, Validators.required),
});
}
onSubmit(event) {
event.preventDefault();
this.formSubmitted = true;
if (this.form.valid) {
this.form.disable();
this.appointment.timestampstart = this.form.get('timestampstart').value;
this.appointment.location = this.form.get('location').value;
this.appointment.description = this.form.get('description').value;
this.appointment.paid = this.form.get('paid').value;
this.appointment.serviceTypeId = this.form.get('serviceType').value;
this.appointment.clientId = this.form.get('client').value;
this.appointment.assignedUserId = this.form.get('assignedUser').value;
this.appointmentService.createNewAppointment(this.appointment)
.subscribe(value => { this.router.navigate([`/dashboard/appointment/${value.id}/edit`]); });
} else {
this.webLogger.error('The form is invalid, please check the values');
}
}
selectTask($event: Event) {
this.task = Number(this.form.get('serviceType').value);
this.availabilityService.getAvailabilityForTask(this.task).subscribe(value => {
this.availability = value;
});
}
setTime($event: Event) {
this.availablemoments = [];
const dayAvailability: Availability[] = this.availability.filter(
s => s.timestampstart.isSame(moment(this.form.get('daystart').value), 'day'));
const currentDate = dayAvailability.reduce((prev, curr) => prev.timestampstart < curr.timestampstart ? prev : curr).timestampstart;
dayAvailability.forEach(value => {
while (value.timestampend.isAfter(currentDate)) {
if (!this.availablemoments.includes(moment(currentDate))) {
this.availablemoments.push(moment(currentDate));
}
currentDate.add(30, 'minutes');
}
});
}
}
this.availability is a list of Availability objects which include start and end moments
I expect the second console log to return the same as the first console log.
UPDATE:
The Availability class looks like this:
export class Availability {
id: number;
timestampstart: Moment;
timestampend: Moment;
location: string;
description: string;
paid: boolean;
payment: Invoice;
serviceType: Task;
client: Client;
assignedUser: User;
static serialize(data: any): Availability {
const user: Availability = Object.assign(new this(), data);
if (data.hasOwnProperty('timestampstart')) {
user.timestampstart = moment(data.timestampstart);
}
if (data.hasOwnProperty('timestampend')) {
user.timestampend = moment(data.timestampend);
}
if (data.hasOwnProperty('serviceType')) {
user.serviceType = Task.serialize(data.serviceType);
}
if (data.hasOwnProperty('client')) {
user.client = Client.serialize(data.client);
}
if (data.hasOwnProperty('assignedUser')) {
user.assignedUser = User.serialize(data.assignedUser);
}
return user;
}
}
I figured it out, since I was using Angular, I assigned the formControlName to the wrong HTML tag (the option tag instead of the select) causing the get of the value to return a value that I wasn't expecting. I've updated the main post to show the entire code.

Angular page auto refresh

I have a little problem in my angular application. On the first page I have a table with a list of all the employees and a "Create New Employee" button, which opens me a new form. After form submitting, a request is sent to the database and I return to the start page. New rows appears only when I click refresh button. Please, tell me, how can I reload data automatically?. Maybe, I do something wrong.
Here is a part of my table.component.html:
<tr *ngFor="let item of getAllEmployees(); let i = index">
<td>{{i+1}}</td>
<td>{{item.firstName}}</td>
<td>{{item.lastName}}</td>
<td [ngSwitch] = "item.isActive">
<span *ngSwitchCase ="1">Yes</span>
<span *ngSwitchDefault>No</span>
</td>
<td>{{item.depName}}</td>
--------------------------------
Here is a part of my table.component.ts:
export class TableComponent{
constructor(private model: Model){
}
getAllEmployees(): Employee[]{
return this.model.getAllEmployees();
}
Here is my Model:
#Injectable()
export class Model{
private employees: Employee[] = new Array<Employee>();
private departments: Department[] = new Array<Department>();
constructor(private dataSource: DataSource){
this.dataSource.getEmployeesData().subscribe(data => this.employees = data);
this.dataSource.getDepsData().subscribe(data => this.departments = data);
}
getAllEmployees(): Employee[]{
return this.employees;
}
And, finally, a request:
export const URL = new InjectionToken("url");
#Injectable()
export class DataSource{
constructor(private http: Http, #Inject(URL) private url: string){
}
getEmployeesData(): Observable<Employee[]>{
return this.sendRequest(RequestMethod.Get, `${this.url}employeeslist`);
}
And also my Form Component:
export class FormComponent{
employee: Employee = new Employee();
constructor(private model:Model, private activeRoute: ActivatedRoute,
private router: Router){
this.editing = activeRoute.snapshot.params["mode"] == "edit";
let id = activeRoute.snapshot.params["id"];
if(id != null){
Object.assign(this.employee, this.model.getEmployee(id) || new Employee());
}
}
editing: boolean = false;
submitForm(form: NgForm) {
if (form.valid) {
this.model.saveEmployee(this.employee);
this.router.navigateByUrl('/');
}
}
resetForm() {
this.employee = new Employee();
}
getAllDeps(): Department[]{
return this.model.getAllDeps();
}
}
Thank you!
Probably your error is here:
export class FormComponent{
employee: Employee = new Employee();
constructor(private model:Model, private activeRoute: ActivatedRoute,
private router: Router){
this.editing = activeRoute.snapshot.params["mode"] == "edit";
let id = activeRoute.snapshot.params["id"];
if(id != null){
Object.assign(this.employee, this.model.getEmployee(id) || new Employee());
}
}
editing: boolean = false;
submitForm(form: NgForm) {
if (form.valid) {
this.model.saveEmployee(this.employee);
this.router.navigateByUrl('/');
}
}
resetForm() {
this.employee = new Employee();
}
getAllDeps(): Department[]{
return this.model.getAllDeps();
}
When you receive a valid form, you save the employee and then redirect to your homepage or index route with this.router.navigateByUrl('/');
Probably you should don't do that and call your getAllEmployees method again to retrieve all the records again

convert and concatenate multiple FormGroup types to object type in Angular 5

Im using mat-stepper of Angular Material design library.
I use 3 separate FormGroups. I would send informations to database using httpClient method, for that I have created an interface :
export interface NouveauProjet {
leadProj: String ;
nomProj: String;
descProj: String;
besProj: Number;
pers: [Personnes];
Backlog: [Fonctionnalite]
}
export interface Personnes {
name: String;
poste:String
}
export interface Fonctionnalite {
fonctionnalite: String;
userStory: String
}
In my component file I create forms and nouveauProject variable that will contain my values .
export class AjoutProjetComponent implements OnInit {
isLinear = false;
firstFormGroup: FormGroup;
secondFormGroup: FormGroup;
thirdFormGroup: FormGroup;
nouveauProjet: NouveauProjet;
constructor(
private _formBuilder: FormBuilder,
private ajoutProj: AjoutprojService
) {}
ngOnInit() {
console.log();
this.firstFormGroup = this._formBuilder.group({
leadProj: ["", Validators.required],
nomProj: ["", Validators.required],
descProj: ["", Validators.required],
besProj: ["", Validators.required]
});
this.secondFormGroup = this._formBuilder.group({
pers: this._formBuilder.array([this.createItem()])
});
this.thirdFormGroup = this._formBuilder.group({
backlog: this._formBuilder.array([this.createFonct()])
});
}
createItem(): FormGroup {
return this._formBuilder.group({
name: ["", Validators.required],
poste: ["", Validators.required]
});
}
createFonct(): FormGroup {
return this._formBuilder.group({
fonctionnalite: ["", Validators.required],
userStory: ["", Validators.required]
});
}
I call my service and before I concatenate formGroup.value.
addProjet() {
this.nouveauProjet =
this.firstFormGroup.value +
this.secondFormGroup.value +
this.thirdFormGroup.value;
console.log(this.nouveauProjet);
this.ajoutProj
.addProj(this.nouveauProjet)
.toPromise()
.then(res => {
console.log(res.json);
});
}
}
In html file I call addProject function then I print {{nouveaProjet | json}} value I get this :
"[object Object][object Object][object Object]"
How to print all values ?
Update: this.firstFormGroup.value, this.secondFormGroup.value, this.thirdFormGroup.value gives in order :
Object cannot be concatenated with + so you could try:
Old way:
var __assign = (this && this.__assign) || Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
this.nouveauProjet = __assign(this.firstFormGroup.value, this.secondFormGroup.value, this.thirdFormGroup.value);
Using ES6 spread operator:
this.nouveauProjet = {
...this.firstFormGroup.value,
...this.secondFormGroup.value,
...this.thirdFormGroup.value
};

Dynamic Validation with nested form

I'm trying to create a nested form with dynamic validation. There's the parent component (finalizaNegociacao) which hold the nested forms (dadosTitular). On the nested form I have a checkbox (handleType) that changes the validation of some fields, like cpf. What should be happening is: When I click on the checkbox cpfis no longer a required field. But even if I click on it it still required. Can someone help me?
Here's the code:
FinalizaNegociacao (parent component), the main logic here is in the recebeValidators :
export class FinalizaNegociacaoComponent implements OnInit, OnChanges {
public dados:dadosAcordo;
public formDadosBancarios: FormGroup;
public submitted: boolean;
public events: any[] = [];
public servError:any;
public servSuccess:any;
cpf_REGEXP = /^\d+$/;
constructor(private _fb: FormBuilder, private finalizaAcordo:FinalizaNegociacaoService) {}
ngOnInit() {
this.formDadosBancarios = this._fb.group({
id: [''],
dados_titular: this._fb.array([
this.initTitular()
])
})
}
initTitular(){
return this._fb.group({
titular: ['', [<any>Validators.required, <any>Validators.minLength(3)]],
cnpj: [''],
cpf: ['', <any>Validators.required],
data_nasc: [''],
agencia: ['', <any>Validators.required ],
banco: ['', <any>Validators.required],
conta: ['', <any>Validators.required],
tipo: ['', <any>Validators.required],
pessoa_juridica: ['']
})
}
addTitular(){
const control = <FormArray> this.formDadosBancarios.controls['dados_titular'];
control.push(this.initTitular());
}
recebeValidators(e:any){
let array = <FormArray> this.formDadosBancarios.get('dados_titular');
let cpf = array.at(0).get("cpf");
let cpfCtrl = this.formDadosBancarios.get(['dados_titular',0,'cpf']);
let cnpj = array.at(0).get('cnpj');
let data_nasc = array.at(0).get('data_nasc');
cpfCtrl = e;
console.log(cpfCtrl);
}
DadosTitular, (Child component), the main logic here is the handleType:
export class TitularComponent {
// we will pass in address from App component
#Input('group')
public titularForm: FormGroup;
#Output() modelChanged = new EventEmitter();
public formDadosBancarios: FormGroup;
cpf_REGEXP = /^\d+$/;
constructor(private _fb: FormBuilder, private finalizaAcordo:FinalizaNegociacaoService) {}
ngOnInit() {
this.formDadosBancarios = this._fb.group({
id: [''],
dados_titular: this._fb.array([
this.initTitular()
])
})
}
initTitular(){
return this._fb.group({
titular: ['', [<any>Validators.required, <any>Validators.minLength(3)]],
cnpj: [''],
cpf: ['', <any>Validators.required],
data_nasc: [''],
agencia: ['', <any>Validators.required ],
banco: ['', <any>Validators.required],
conta: ['', <any>Validators.required],
tipo: ['', <any>Validators.required],
pessoa_juridica: ['']
})
}
handleType(isJuridica: boolean, i:number, e:any): void {
let array = <FormArray> this.formDadosBancarios.get('dados_titular');
let cpf = array.at(0).get("cpf");
let cnpj = array.at(0).get('cnpj');
let data_nasc = array.at(0).get('data_nasc');
const cpfCtrl = this.formDadosBancarios.get(['dados_titular',0,'cpf']);
const cnpjCtrl = this.formDadosBancarios.get(['dados_titular',0, 'cnpj']);
const data_nascCtrl = this.formDadosBancarios.get(['dados_titular',0,'data_nasc']);
const reqValidators: ValidatorFn[] = [Validators.required, Validators.pattern(this.cpf_REGEXP)];
if (isJuridica) {
cpfCtrl.setValidators(null);
data_nascCtrl.setValidators(null);
cnpjCtrl.setValidators(reqValidators);
this.modelChanged.emit(cpfCtrl);
}else{
cpfCtrl.setValidators(reqValidators);
data_nascCtrl.setValidators(reqValidators)
cnpjCtrl.setValidators(null);
this.modelChanged.emit(cpfCtrl);
}
cpfCtrl.updateValueAndValidity();
data_nascCtrl.updateValueAndValidity();
cnpjCtrl.updateValueAndValidity();
}
}
and there's the html:
<div formArrayName="dados_titular">
<div *ngFor="let dados_titular of formDadosBancarios.controls.dados_titular.controls; let i=index">
<div [formGroupName]="i">
<titular (modelChanged)="recebeValidators($event)" [group]="formDadosBancarios.controls.dados_titular.controls[i]"></titular>
</div>
</div>
</div>

Categories