Ionic4 ngSubmit is not firing on submit - angular4-forms

Using Ionic4 for the first time and struggling with ngSubmit not triggering the respective method in the login page. Although its always successfully hitting the LoginPage constructor and AuthService constructor. All the respective modules have been imported and there are no console errors too. What am i doing wrong ?
login.page.html:
<ion-header>
<ion-toolbar>
<ion-title>
Login
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<form (ngSubmit)="login()" [formGroup]="loginForm">
<ion-grid>
<ion-row>
<ion-col>
<ion-item>
<ion-input type="text" placeholder="Email" formControlName="email" style="width:50%;"></ion-input>
</ion-item>
</ion-col>
</ion-row>
<ion-row>
<ion-col col-3>
<ion-item>
<ion-input type="password" placeholder="Password" formControlName="password" style="width:50%;"></ion-input>
</ion-item>
</ion-col>
</ion-row>
</ion-grid>
<div padding-horizontal>
<div class="form-error">{{loginError}}</div>
</div>
<ion-grid>
<ion-row>
<ion-col>
<ion-button type="submit" [disabled]="!loginForm.valid" color="primary">Log in</ion-button>
Forgot password?
</ion-col>
</ion-row>
<ion-row>
<ion-col>
<ion-button icon-left block clear (click)="loginWithGoogle()" color="secondary">
<ion-icon name="logo-google"></ion-icon>
Log in with Google
</ion-button>
<ion-button icon-left block clear (click)="signup()" color="primary">
<ion-icon name="person-add"></ion-icon>
Sign up
</ion-button>
</ion-col>
</ion-row>
</ion-grid>
</form>
</ion-content>
login.page.ts:
import { Component, OnInit } from '#angular/core';
import { AuthService } from '../common/services/auth.service';
import { FormGroup, FormBuilder, Validators } from '#angular/forms';
import { Router } from '#angular/router';
#Component({
selector: 'app-login',
templateUrl: './login.page.html',
styleUrls: ['./login.page.scss'],
})
export class LoginPage implements OnInit {
loginForm: FormGroup;
loginError: string;
constructor(private auth:AuthService,
private router:Router,
private fb: FormBuilder)
{
this.loginForm = this.fb.group({
email: ['', Validators.compose([Validators.required, Validators.email])],
password: ['', Validators.compose([Validators.required, Validators.minLength(6)])]
});
}
ngOnInit() {}
login() {
alert('login');
let data = this.loginForm.value;
if (!data.email) {
return;
}
let credentials = {
email: data.email,
password: data.password
};
this.auth.signInWithEmail(credentials)
.then(
() => this.router.navigate(['/home']),
error => this.loginError = error.message
);
}
}
login.module.ts:
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { FormsModule,ReactiveFormsModule } from '#angular/forms';
import { Routes, RouterModule } from '#angular/router';
import { IonicModule } from '#ionic/angular';
import { LoginPage } from './login.page';
const routes: Routes = [
{
path: '',
component: LoginPage
}
];
#NgModule({
imports: [
CommonModule,
FormsModule,
ReactiveFormsModule,
IonicModule,
RouterModule.forChild(routes),
],
entryComponents: [LoginPage],
declarations: [LoginPage]
})
export class LoginPageModule {}
auth.service.ts:
import { Injectable } from '#angular/core';
import { AngularFireAuth } from 'angularfire2/auth';
import * as firebase from 'firebase/app';
import AuthProvider = firebase.auth.AuthProvider;
#Injectable({
providedIn: 'root'
})
export class AuthService {
private user: firebase.User;
constructor(public afAuth: AngularFireAuth) {
afAuth.authState.subscribe(user => {
this.user = user;
});
}
signInWithEmail(credentials) {
console.log('Sign in with email');
return this.afAuth.auth.signInWithEmailAndPassword(credentials.email,
credentials.password);
}
}

ngSubmit is reloading the complete page and hence its hitting only login constructor but not the respective method. Removed (ngSubmit) on <form>, type="submit" on <ion-button>, added (click)="login()" event to <ion-button>. It started working.

Related

Login using API in Ionic 6

## login.page.ts ##
import { Component, OnInit } from '#angular/core';
import { AuthService } from 'src/services/auth/auth.service';
import { NavController } from '#ionic/angular';
import { AlertService } from 'src/services/alert/alert.service';
import { NgForm } from '#angular/forms';
#Component({
selector: 'app-login',
templateUrl: './login.page.html',
styleUrls: ['./login.page.scss']
})
export class LoginPage implements OnInit {
constructor(
private authService: AuthService,
private navCtrl: NavController,
private alertService: AlertService
) { }
ngOnInit() {
}
onLogin(form: NgForm) {
this.authService.login(form.value.username, form.value.password).subscribe(
() => {
this.alertService.presentToast("Logged In");
this.navCtrl.navigateRoot('/welcome');
},
error => {
console.log(error);
},
() => {
this.alertService.presentToast("Failed");
this.navCtrl.navigateRoot('/login');
}
);
}
}
## login.page.scss ##
ion-content.background{
--background: url(../../assets/img/staffandtruck.jpg) 0 0/100% 100% no-repeat;
}
## login.page.html ##
<ion-content padding class="background">
<ion-card>
<img src="assets/img/logo2.png"/>
</ion-card>
<ion-card>
<ion-card-content>
<form #form="ngForm" (ngSubmit)="onLogin(form)">
<ion-item>
<ion-icon slot="start" name="person-circle"></ion-icon>
<ion-label position="floating">Staff ID</ion-label>
<ion-input type="email" name="username" ngModel required></ion-input>
</ion-item>
<ion-item>
<ion-icon slot="start" name="key"></ion-icon>
<ion-label position="floating">Password</ion-label>
<ion-input type="password" name="password" ngModel required></ion-input>
</ion-item>
<ion-card-content>
<ion-button expand="block" color="primary" type="submit">Log in</ion-button>
</ion-card-content>
</form>
</ion-card-content>
</ion-card>
</ion-content>
i am new here and beginner in Ionic Framework. Is there anyone can help me and teach me on how to create a login using API that call username and password without create a Model for User? I don't know how to startup and implement this API. This is my environment setup for Ionic.
My environment setup for Ionic. This is for environment service that calling API for login EnvService.ts. This is for auth service AuthService.ts. But, that all not functioning as I wish.

Ionic signature-pad

I have install 'angular2-signaturepad' in my ionic project, and I created a test app and that's working fine, But when I try to integrate with my existing project shows me 'signature-pad' is not a known element' and '
<ion-content padding>
<signature-pad [ERROR ->][options]="signaturePadOptions"
(onBeginEvent)="drawStart()" (onEndEvent)="drawComplete()"></signatur"):
ng:///SignPageModule/SignPage.html#10:16
'signature-pad' is not a known element:
1. If 'signature-pad' is an Angular component, then verify that it is part of this module.
2. If 'signature-pad' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '#NgModule.schemas' of this component to suppress this message. ("
<ion-content padding>
[ERROR ->]<signature-pad [options]="signaturePadOptions" (onBeginEvent)="drawStart()" (onEndEvent)="drawComplet"): ng:///SignPageModule/SignPage.html#10:1
Error: Template parse errors:
Can't bind to 'options' since it isn't a known property of 'signature-pad'.
1. If 'signature-pad' is an Angular component and it has 'options' input, then verify that it is part of this module.
2. If 'signature-pad' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '#NgModule.schemas' of this component to suppress this message.
3. To allow any property add 'NO_ERRORS_SCHEMA' to the '#NgModule.schemas' of this component
This is the error I m facing. I was added 'CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA' in my app.module.ts file.
This is my sign.html code:
<ion-header>
<ion-navbar>
<ion-title>sign</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<ion-row [ngClass]="{'drawing-active': isDrawing}">
<ion-col></ion-col>
<ion-col style="border: 1px solid #5d6691;">
<signature-pad [options]="signaturePadOptions" (onBeginEvent)="drawStart()" (onEndEvent)="drawComplete()" style="width: 50px; height: 580px; color: red;"> </signature-pad>
</ion-col>
<ion-col></ion-col>
</ion-row>
<ion-row>
<ion-col>
<button ion-button style="color: #fff; background: #e59c9c;" (click)="clearPad()">Clear</button>
</ion-col>
<ion-col>
<button ion-button style="color: #fff; background: #4355a5;" (click)="savePad()">Save</button>
</ion-col>
<ion-col>
<button ion-button style="color: #fff; background: #e59c9c;" (click)="delPad()">delete</button>
</ion-col>
</ion-row>
<ion-row text-center>
<ion-col width-120>
<img [src]="signature" [hidden]= "signature == '' || signature == undefined " style="height: 200px;" />
</ion-col>
</ion-row>
This is my sign.ts code:
import { Component, ViewChild } from '#angular/core';
import { IonicPage, NavController, NavParams, ToastController } from 'ionic-angular';
import { SignaturePad } from 'angular2-signaturepad/signature-pad';
import { Storage } from '#ionic/storage';
#IonicPage()
#Component({
selector: 'page-sign',
templateUrl: 'sign.html',
})
export class SignPage {
public signature = '';
isDrawing = false;
#ViewChild(SignaturePad) signaturePad: SignaturePad;
private signaturePadOptions: Object = {
'minWidth': 1,
'canvasWidth': 320,
'canvasHeight': 200,
'backgroundColor': '#f6fbff',
'penColor': '#06219b'
};
constructor(public navCtrl: NavController,
public navParams: NavParams,
public storage: Storage,
public toastCtrl: ToastController ) {
}
ionViewDidLoad() {
this.signaturePad.clear()
this.storage.get('savedSignature').then((data) => {
this.signature = data;
});
}
drawComplete() {
this.isDrawing = false;
}
drawStart() {
this.isDrawing = true;
}
savePad() {
this.signature = this.signaturePad.toDataURL();
this.storage.set('savedSignature', this.signature);
this.signaturePad.clear();
let toast = this.toastCtrl.create({
message: 'New Signature saved.',
cssClass: 'homeToast',
duration: 3000,
position: 'top'
});
toast.present();
}
clearPad() {
this.signaturePad.clear();
}
delPad(){
this.storage.clear();
this.signature = '';
}
}
This is my app.module.ts code:
import { BrowserModule } from '#angular/platform-browser';
import { ErrorHandler, NgModule, CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA } from '#angular/core';
import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular';
import { SplashScreen } from '#ionic-native/splash-screen';
import { StatusBar } from '#ionic-native/status-bar';
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
import { SignaturePadModule } from 'angular2-signaturepad';
import { IonicStorageModule } from '#ionic/storage';
#NgModule({
declarations: [
MyApp,
HomePage
],
imports: [
BrowserModule,
IonicModule.forRoot(MyApp,{
backButtonText: '',
autoFocusAssist: true }),
SignaturePadModule,
IonicStorageModule.forRoot()
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
HomePage
],
providers: [
StatusBar,
SplashScreen,
{provide: ErrorHandler, useClass: IonicErrorHandler}
],
schemas: [ CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA ]
})
export class AppModule {}
I expected signature-pad to be working fine
Make sure to also import the module in sign.module.ts
import { SignaturePadModule } from 'angular2-signaturepad';
#NgModule({
imports: [
...
SignaturePadModule
],
declarations: [SignPage]
})
export class SignPageModule {}

Ionic 4 background blinks and tap delay

This is my first application using ionic4 and there is something weird happening. When I tap on any link, there is delay and the entire background blinks before it loads the page. Here is a video showing this weird behave: https://youtu.be/NqoOMQYyr4k
For reference, here is the code for the pages:
On the global.scss i have this property to setup the background
ion-content {
--background: #000 url('./assets/images/main-bg.png') no-repeat center center / cover;
}
news.page.ts
import { News } from './news.model';
import { Component, OnInit } from '#angular/core';
import { NewsService } from '../services/news.service';
import { Router } from '#angular/router';
import { NavController } from '#ionic/angular';
#Component({
selector: 'app-news',
templateUrl: './news.page.html',
styleUrls: ['./news.page.scss'],
})
export class NewsPage implements OnInit {
news: any;
constructor(private newsService: NewsService, private router: Router, private navController: NavController) { }
ngOnInit() {
this.news = this.newsService.getAllEvents();
}
go(id: string) {
this.navController.navigateForward('news/' + id);
}
}
news.page.html
<ion-header>
<ion-toolbar color="grey">
<ion-buttons slot="start">
<ion-menu-button></ion-menu-button>
</ion-buttons>
<ion-title style="color: #524A4A!important">News</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-grid padding class="margin-logo-header">
<ion-row>
<div>
<h2>Noticias HD Friends</h2>
</div>
</ion-row>
</ion-grid>
<ion-card color="grey" *ngFor="let news of news | async">
<ion-nav-pop (click)="go(news.id)" >
<ion-img src="{{news.picture}}"></ion-img>
<ion-card-header>
<ion-card-title>{{ news.title }}</ion-card-title>
</ion-card-header>
<ion-card-content>
<p>{{ news.subtitle }}</p>
</ion-card-content>
</ion-nav-pop>
</ion-card>
</ion-content>
news.service.ts
import { Injectable } from '#angular/core';
import { AngularFireDatabase, AngularFireList } from '#angular/fire/database';
import { News } from '../news/news.model';
#Injectable({
providedIn: 'root'
})
export class NewsService {
NODE = 'news/';
news: AngularFireList<News[]>;
constructor(private db: AngularFireDatabase) { }
getAllEvents() {
const localNews = this.db.list(this.NODE);
return localNews.valueChanges();
}
getNews(id: string) {
return this.db.object(this.NODE + id);
}
}
Is this a bug because it's a beta or is this something I messed up?
Thanks guys
UPDATE 1
This seems to be a bug on ionic framework. As soon as I get something I'll post here for future reference.

Ionic 2 Maximum call stack size exceeded Error

Trying to figure out this problem. I am getting a maxmimum call stack size error and the link below is the js output.
I have added print statements and worked out the main app file is calling page1 as it should but then page1 is calling the main app file and this continues.
I am new to ionic 2 and would really appreciate a solution, thanks.
Javascript Output
page1.ts
import { Component } from '#angular/core';
import { Data } from '../../providers/data';
import { NewListPage } from '../new-list/new-list';
import { NavController } from 'ionic-angular';
#Component({
selector: 'page-page1',
templateUrl: 'page1.html',
})
export class Page1 {
public list: any[] = [];
constructor(public navCtrl: NavController, private _data: Data) {
console.log('Page1BEFORE');
let that = this;
this._data.list.subscribe((data) => {that.list.push(data);}, (err) => {console.error(err);});
}
newList() {
console.log('NEWLIST1');
this.navCtrl.push(NewListPage);
}
}
page1.html
<ion-app>
<ion-header>
<ion-navbar>
<button ion-button menuToggle>
<ion-icon name="menu"></ion-icon>
</button>
<ion-title>Page One</ion-title>
<ion-buttons end>
<ion-icon ios="ios-contact" md="md-contact"></ion-icon>
</ion-buttons>
</ion-navbar>
</ion-header>
<ion-content class="grid-basic-page">
<ion-col width-100><progress class="progressBar" max="100" value="80"></progress></ion-col>
<ion-row>
<ion-col width-50><div>col</div></ion-col>
<ion-col width-50><div>col</div></ion-col>
</ion-row>
<ion-row>
<ion-col width-50><div>col</div></ion-col>
<ion-col width-50><div>col</div></ion-col>
</ion-row>
<ion-row>
<ion-col width-50><div>col</div></ion-col>
<ion-col width-50><div>col</div></ion-col>
</ion-row>
<ion-list *ngIf="list">
<ion-item *ngFor="let item of list">
<ion-label>{{item.title}}</ion-label>
</ion-item>
</ion-list>
<p *ngIf="!list"> No Lists </p>
<button fab fab-bottom fab-right (click)="newList()"> New </button>
</ion-content>
</ion-app>
app.component.ts
import { Component, ViewChild } from '#angular/core';
import { Nav, Platform } from 'ionic-angular';
import { StatusBar, Splashscreen } from 'ionic-native';
import { Page1 } from '../pages/page1/page1';
import { Page2 } from '../pages/page2/page2';
import { Data } from '../providers/data';
#Component({
templateUrl: 'app.html',
providers: [Data],
})
export class MyApp {
#ViewChild(Nav) nav: Nav;
rootPage: any = Page1;
pages: Array<{title: string, component: any}>;
constructor(public platform: Platform) {
console.log('PreAPP');
this.initializeApp();
console.log('PostApp');
// used for an example of ngFor and navigation
this.pages = [
{ title: 'Page One', component: Page1 },
{ title: 'Page Two', component: Page2 }
];
console.log('pages');
}
initializeApp() {
console.log('APP');
this.platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
StatusBar.styleDefault();
Splashscreen.hide();
});
}
openPage(page) {
console.log('OpenPAGE');
// Reset the content nav to have just this page
// we wouldn't want the back button to show in this scenario
this.nav.setRoot(page.component);
}
}
app.html
<ion-menu [content]="content">
<ion-header>
<ion-toolbar>
<ion-title>Menu</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-list>
<button menuClose ion-item *ngFor="let p of pages" (click)="openPage(p)">
{{ p.title }}
</button>
</ion-list>
</ion-content>
</ion-menu>
<!-- Disable swipe-to-go-back because it's poor UX to combine STGB with side menus -->
<ion-nav [root]="rootPage" #content swipeBackEnabled="false"></ion-nav>
Removing the <ion-app> element from page1.html fixed the issue
In my case I had not declared and added routes constant in imports array of the module. Once declared and imported error gone.
I am using IONIC 4

Ionic2 serve shows blank screen after using formbuilder

I have a Login page. It was working fine. I changed the login form to use FormBuilder.
There is no error during build process or any reported in the developer tool. But the application shows blank screen when running with ionic serve.
Below is the code changed in login.html.
<form [formGroup]="loginForm" (ngSubmit)="login(loginForm.value)" >
<ion-row>
<ion-col>
<ion-list inset>
<ion-item>
<ion-input type="text" placeholder="Username" formControlName="username" ></ion-input>
</ion-item>
<p *ngIf="username.hasError('required') && username.touched" danger>Username is required</p>
<ion-item>
<ion-input type="password" placeholder="Password" formControlName="password"></ion-input>
</ion-item>
<p *ngIf="password.hasError('required') && password.touched" danger>Password is required</p>
</ion-list>
</ion-col>
</ion-row>
<ion-row>
<ion-col class="signup-col">
<button ion-button class="submit-btn" full type="submit" [disabled]="!loginForm.valid">Login</button>
<button ion-button class="register-btn" block clear (click)="createAccount()">Create New Account</button>
</ion-col>
</ion-row>
</form>
Below is the code changed in login.ts.
import { Component } from '#angular/core';
import { NavController, AlertController, LoadingController, Loading } from 'ionic-angular';
import { FormBuilder, FormGroup, FormControl, Validators } from '#angular/forms';
import { AuthService } from '../../providers/auth-service';
import { RegisterPage } from '../register/register';
import { HomePage } from '../home/home';
#Component({
selector: 'page-login',
templateUrl: 'login.html'
})
export class LoginPage {
loading: Loading;
registerCredentials = {username: '', password: ''};
loginForm: FormGroup;
username: FormControl;
password: FormControl;
constructor(private nav: NavController, private auth: AuthService,
private alertCtrl: AlertController, private loadingCtrl: LoadingController,
public formBuilder: FormBuilder) {
this.loginForm = formBuilder.group({
username: ['', Validators.required],
password: ['', Validators.required],
});
this.username = this.loginForm['username'];
this.password = this.loginForm['password'];
}