Interface, Angular 5, Reactive Form - interface

I have created an interface for login and getting and error when I am trying to compile it
error :Type 'FormGroup' is not assignable to type 'IAuth'. Property 'email' is missing in type 'FormGroup'
auth.ts
export interface IAuth{
email : String;
password : String;
}
login.component.ts
import { HomePage } from './../home/home';
import { FormBuilder, FormGroup, Validators, FormControl } from '#angular/forms';
import { Component } from '#angular/core';
import { IAuth } from '../../models/auth';
#Component({
selector: 'page-login',
templateUrl: 'login.html',
})
export class LoginPage {
userAuth : IAuth;
constructor ( private formBuilder : FormBuilder)
{
this.userAuth = formBuilder.group({
email : new FormControl('',Validators.required),
password : new FormControl('',Validators.required)
});
}
}

Related

How to creat a dynamic text

I have a list of titles, and I would like these texts to alternate as I switch to ion-select. How do I do this?
I have no idea how to do this, not even what part of the code to show. I made an attempt here but whenever I use the console the value returned is undefined.
My typescrit code:
import { Titulo } from './../Services/services.service';
import { DataService } from './data.service';
import { Component, OnInit, ViewChild} from '#angular/core';
import {IonSlides} from '#ionic/angular';
import { ActivatedRoute } from '#angular/router';
#Component({
selector: 'app-libertacao',
templateUrl: './libertacao.page.html',
styleUrls: ['./libertacao.page.scss'],
})
export class LibertacaoPage implements OnInit {
#ViewChild(IonSlides) slides: IonSlides;
PAGINA_SELECIONADA: number;
// tslint:disable-next-line: variable-name
index_atual: number;
titulo: Titulo;
constructor(private dataservice: DataService, private activatedRoute: ActivatedRoute ){
}
ngOnInit() {
const id = this.activatedRoute.snapshot.paramMap.get('id');
this.titulo = this.dataservice.getTituloById(parseInt(id, 10));
}
OnChange(event: any)
{
if (event.detail.value === this.PAGINA_SELECIONADA) {
this.slides.slideTo(this.PAGINA_SELECIONADA);
}
else {}
console.log(this.titulo);
}
slideChanged() {
this.slides.getActiveIndex().then((index) => {
this.index_atual = index;
});
}
}

Add Components dynamically in DOM ionic+angular

I am following How to Dynamically Create a Component in Angular to add components dynamically inside another component. I am receiving a weired error of undefined variable.
My Component file (MessComponent)
<template #messContainer>
<p>
mess works!
</p>
</template>
ts file
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-mess',
templateUrl: './mess.component.html',
styleUrls: ['./mess.component.scss'],
})
export class MessComponent implements OnInit {
constructor() { }
ngOnInit() {}
}
Parent Component (hosting dynamic component)
module ts file
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '#angular/core';
import { CommonModule } from '#angular/common';
import { IonicModule } from '#ionic/angular';
import { FormsModule } from '#angular/forms';
import { HomePage } from './home.page';
import { HomePageRoutingModule } from './home-routing.module';
import { MessComponent } from './../mess/mess.component';
#NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
HomePageRoutingModule
],
declarations: [HomePage, MessComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
entryComponents: [MessComponent]
})
export class HomePageModule {}
ts file
import { Component, ViewChild, ViewContainerRef, ComponentFactoryResolver, ComponentRef, ComponentFactory, OnInit } from "#angular/core";
import { MessComponent } from "./../mess/mess.component";
#Component({
selector: "app-home",
templateUrl: "home.page.html",
styleUrls: ["home.page.scss"],
})
export class HomePage implements OnInit {
componentRef: any;
#ViewChild('messContainer', { read: ViewContainerRef, static: true }) entry: ViewContainerRef;
createComponent() {
this.entry.clear();
const factory = this.resolver.resolveComponentFactory(MessComponent);
this.componentRef = this.entry.createComponent(factory);
}
destroyComponent() {
this.componentRef.destroy();
}
constructor(private resolver: ComponentFactoryResolver) {}
ngOnInit(): void {
this.createComponent();
}
}
and the error I am receiving
Uncaught (in promise): TypeError: this.entry is undefined
I understand this is claiming regarding the variable entry, but don't understand why it is not identifying that variable. To conclude, why I cannot add the component?
Solved it. Actually I was passing wrong param to the #ViewChild(''). I was passing the template name (container) of the child while I should have passed the container name in the parent component. So created a div in the parent component with #messContainer and corrected the #ViewChild
Important!:
now #messContainer is in the parent component and everything works as expected.
#ViewChild('messContainer', { read: ViewContainerRef, static: true }) entry: ViewContainerRef;

Use property as form validator in Angular2 (data-driven)

I'm having a hard time trying to set a max value using the data driven approach in Angular2.
I want to set the max value of the input to a property called userLimit, which I get from firebase. This is my code:
component.ts
import { Component, OnInit, AfterViewInit } from '#angular/core';
import { FormBuilder, FormGroup, Validators, FormControl } from "#angular/forms";
import { FiredbService } from '../services/firedb.service';
import { AuthService } from '../services/auth.service';
import { AngularFireDatabase, FirebaseListObservable, FirebaseObjectObservable } from 'angularfire2/database';
#Component({
selector: 'my-dashboard',
styleUrls: ['./recibirpago.component.scss'],
templateUrl: './recibirpago.component.html'
})
export class RecibirpagoComponent implements OnInit, AfterViewInit {
myForm2: FormGroup;
uid: string;
userLimit: any;
constructor(private fb: FormBuilder,
private dbfr: FiredbService,
private db: AngularFireDatabase,
private authService: AuthService) {
this.myForm2 = this.fb.group({
email: ['', Validators.email],
clpmount: ['', [Validators.required, Validators.max(this.userLimit)]]
});
}
ngOnInit() {
this.uid = this.authService.getUserUid();
}
ngAfterViewInit() {
this.dbfr.getUserLimit(this.uid).subscribe(snapshot => {
this.userLimit = snapshot.val().accountLimit;
console.log(this.userLimit);
})
}
If I write, for example, Validators.max(5000) it works, but if I try to get the data from Firebase it doesn't work.
Thanks for your help!
The problem is that the constructor is executing before the ngAfterViewInit so you don't have the value of the userLimit at that point.
Instead use the setVAlidators method within the subscribe where you get the data.
Something like this:
constructor
this.myForm2 = this.fb.group({
email: ['', Validators.email],
clpmount: ['', Validators.required] // <-- not here
});
ngAfterViewInit
ngAfterViewInit() {
this.dbfr.getUserLimit(this.uid).subscribe(snapshot => {
this.userLimit = snapshot.val().accountLimit;
console.log(this.userLimit);
const clpControl = this.myForm2.get(`clpmount');
clpControl.setValidators(Validators.max(this.userLimit)); // <-- HERE
clpControl.updateValueAndValidity();
})
}
NOTE: Syntax was not checked.

Accordion List within ionic 2

I've create a custom components named Accordion within iconic 2 and working in browser perfectly but on device not working.
I've split my code up into components, where
Home.ts
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import {DataCards} from '../../components/data-cards/data-cards';
import {Data} from '../../components/data/data';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
public dataList: Data[];
constructor(public navCtrl: NavController) {
this.dataList = [
new Data('title 1', 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. ','ios-remove-circle-outline', true),
new Data('title 2', 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. ','ios-add-circle-outline', false),
new Data('title 3', 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. ','ios-add-circle-outline', false)
];
}
}
and the corresponding HTML
<ion-content padding>
<data-cards [data]="dataList"></data-cards>
</ion-content>
contain my custom component data-cards. data-cards has an input parameter data, through which the list of data is passed.
data.ts
import { Component } from '#angular/core';
#Component({
selector: 'data',
templateUrl: 'data.html'
})
export class Data {
constructor(public title: string, public details: string, public icon: string, public showDetails: boolean) {}
}
data-cards.ts
import { Component } from '#angular/core';
import { Data } from '../data/data';
#Component({
selector: 'data-cards',
inputs: ['data'],
templateUrl: 'data-cards.html'
})
export class DataCards {
public data: Data[];
constructor() {}
toggleDetails(data: Data) {
if (data.showDetails) {
data.showDetails = false;
data.icon = 'ios-add-circle-outline';
} else {
data.showDetails = true;
data.icon = 'ios-remove-circle-outline';
}
}
}
app.module.ts
import { NgModule } from '#angular/core';
import { IonicApp, IonicModule } from 'ionic-angular';
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
import { Data } from '../components/data/data';
import { DataCards } from '../components/data-cards/data-cards';
#NgModule({
declarations: [
MyApp,
HomePage,
Data,
DataCards
],
imports: [
IonicModule.forRoot(MyApp)
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
HomePage,
Data,
DataCards
],
providers: []
})
export class AppModule {}
When run on iOS ( ionic run ios ) i've got an error like below :
[08:44:54] Error: Error at /Users/imac/Documents/ionic2Accordion/.tmp/components/data/data.ngfactory.ts:29:71
[08:44:54] Property 'string' does not exist on type 'typeof "/path/ionic2Accordion/.tmp/components/data/data"'.
[08:44:54] Error at /path/ionic2Accordion/.tmp/components/data/data.ngfactory.ts:29:111
[08:44:54] Property 'string' does not exist on type 'typeof "/path/ionic2Accordion/.tmp/components/data/data"'.
[08:44:54] Error at /path/ionic2Accordion/.tmp/components/data/data.ngfactory.ts:29:151
[08:44:54] Property 'string' does not exist on type 'typeof "/path/ionic2Accordion/.tmp/components/data/data"'.
[08:44:54] Error at /path/ionic2Accordion/.tmp/components/data/data.ngfactory.ts:29:191
[08:44:54] Property 'boolean' does not exist on type 'typeof "/path/ionic2Accordion/.tmp/components/data/data"'.
[08:44:54] ngc failed
[08:44:54] ionic-app-script task: "build"
[08:44:54] Error: Error
so my question : how i can resolve this problem any suggestion ?
In data-card.ts change
public data: Data[];
o be
Input() data: Data[];
since you will be assigning it from the component creation in the home.html? You'll also need to import the Input module via
import { Component, Input } from '#angular/core';

How to perform async validation using reactive/model-driven forms in Angular 2

I have an email input and I want to create a validator to check, through an API, if the entered email it's already in the database.
So, I have:
A validator directive
import { Directive, forwardRef } from '#angular/core';
import { Http } from '#angular/http';
import { NG_ASYNC_VALIDATORS, FormControl } from '#angular/forms';
export function validateExistentEmailFactory(http: Http) {
return (c: FormControl) => {
return new Promise((resolve, reject) => {
let observable: any = http.get('/api/check?email=' + c.value).map((response) => {
return response.json().account_exists;
});
observable.subscribe(exist => {
if (exist) {
resolve({ existentEmail: true });
} else {
resolve(null);
}
});
});
};
}
#Directive({
selector: '[validateExistentEmail][ngModel],[validateExistentEmail][formControl]',
providers: [
Http,
{ provide: NG_ASYNC_VALIDATORS, useExisting: forwardRef(() => ExistentEmailValidator), multi: true },
],
})
export class ExistentEmailValidator {
private validator: Function;
constructor(
private http: Http
) {
this.validator = validateExistentEmailFactory(http);
}
public validate(c: FormControl) {
return this.validator(c);
}
}
A component
import { Component } from '#angular/core';
import { FormGroup, FormBuilder, Validators } from '#angular/forms';
import { ExistentEmailValidator } from '../../directives/existent-email-validator';
#Component({
selector: 'user-account',
template: require<string>('./user-account.component.html'),
})
export class UserAccountComponent {
private registrationForm: FormGroup;
private registrationFormBuilder: FormBuilder;
private existentEmailValidator: ExistentEmailValidator;
constructor(
registrationFormBuilder: FormBuilder,
existentEmailValidator: ExistentEmailValidator
) {
this.registrationFormBuilder = registrationFormBuilder;
this.existentEmailValidator = existentEmailValidator;
this.initRegistrationForm();
}
private initRegistrationForm() {
this.registrationForm = this.registrationFormBuilder.group({
email: ['', [this.existentEmailValidator]],
});
}
}
And a template
<form novalidate [formGroup]="registrationForm">
<input type="text" [formControl]="registrationForm.controls.email" name="registration_email" />
</form>
A've made other validator this way (without the async part) and works well. I think te problem it's related with the promise. I'm pretty sure the code inside observable.subscribe it's running fine.
What am I missing?
I'm using angular v2.1
Pretty sure your problem is this line:
...
email: ['', [this.existentEmailValidator]],
...
You're passing your async validator to the synchronous validators array, I think the way it should be is this:
...
email: ['', [], [this.existentEmailValidator]],
...
It would probably be more obvious if you'd use the new FormGroup(...) syntax instead of FormBuilder.