Error TS2339: Property 'u_email_address' does not exist on type 'LoginPage'

Hi, I tried to make a login & register page using mysql and php as the backend, but the toast timeout (image 1 below) keep came out yet the data is been saved (image 2 below)

image 1

image 2

There is no error after click on the register button except Timeout alert, but there are few errors like this


This is my code in login.page.html

<ion-header no-border>
  <ion-toolbar color="warning">
    <ion-title>Login</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
  <ion-list>
    <div class="">
      <ion-item>
        <ion-label position="floating">Email</ion-label>
        <ion-input type="text" [(ngModel)]="u_email_address"></ion-input>
      </ion-item>
    
      <ion-item>
        <ion-label position="floating">Password</ion-label>
        <ion-input type="password" [(ngModel)]="u_password"></ion-input>
      </ion-item>
      <br><br><br>
      <ion-button expand="block" class="ion-padding" color="warning" (click)="tryLogin()">Login</ion-button>
  </div>

    <p class="ion-text-center info-1">
      <br>Don't have an account? <span (click)="openRegister()">Register now</span>
    </p>
  </ion-list>
</ion-content>

login.page.ts

import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-login',
  templateUrl: './login.page.html',
  styleUrls: ['./login.page.scss'],
})
export class LoginPage implements OnInit {

  constructor(
    private router : Router
  ) { }

  ngOnInit() {
  }

  openRegister(){
    this.router.navigate(['/register']);
  }

}

register.page.html

<ion-header no-border>
  <ion-toolbar color="warning">
    <ion-title>Register</ion-title>
    <ion-buttons slot="start">
      <ion-back-button></ion-back-button>
    </ion-buttons>
  </ion-toolbar>
</ion-header>

<ion-content>
  <ion-list>
    <div class="">
      <ion-item>
        <ion-label position="floating">Name</ion-label>
        <ion-input type="text" [(ngModel)]="u_name"></ion-input>
      </ion-item>
    
      <ion-item>
        <ion-label position="floating">Email</ion-label>
        <ion-input type="text" [(ngModel)]="u_email_address"></ion-input>
      </ion-item>

      <ion-item>
        <ion-label position="floating">Password</ion-label>
        <ion-input type="password" [(ngModel)]="u_password"></ion-input>
      </ion-item>
    
      <ion-item>
        <ion-label position="floating">Confirm Password</ion-label>
        <ion-input type="password" [(ngModel)]="u_confirm_password"></ion-input>
      </ion-item>
      <br><br><br>
      <ion-button expand="block" class="ion-padding" color="warning" (click)="tryRegister()" [disabled]="disabledButton">Register</ion-button>
  </div>
  </ion-list>
</ion-content>

register.page.ts

import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { ToastController, LoadingController, AlertController } from '@ionic/angular';
import { AccessProviders } from '../providers/access-providers';

@Component({
  selector: 'app-register',
  templateUrl: './register.page.html',
  styleUrls: ['./register.page.scss'],
})
export class RegisterPage implements OnInit {

  u_name          : string = "";
  u_email_address : string = "";
  u_password      : string = "";
  u_confirm_password : string = "";

  disabledButton;

  constructor(
    private router : Router,
    private toastCtrl : ToastController,
    private loadingCtrl : LoadingController,
    private alertCtrl : AlertController,
    private accsPrvds: AccessProviders
  ) { }

  ngOnInit() {
  }

  ionViewDidEnter(){
    this.disabledButton = false;
  }

  async tryRegister(){
    if(this.u_name == ""){
      this.presentToast('Name is required');
    }else if(this.u_email_address == ""){
      this.presentToast('Email is required');
    }else if(this.u_password == ""){
      this.presentToast('Password is required');
    }else if(this.u_confirm_password != this.u_password){
      this.presentToast('Password are not the same');
    }else{
      this.disabledButton = true;
      const loader = await this.loadingCtrl.create({
        message: 'Please wait a moment...',
      });
      loader.present();

      return new Promise(resolve =>{
        let body = {
          aksi: 'proses_register',
          u_name: this.u_name,
          u_email_address: this.u_email_address,
          u_password: this.u_password
        }

        this.accsPrvds.postData(body, 'proses_api.php').subscribe((res:any)=>{
          if(res.success==true){
            loader.dismiss();
            this.disabledButton = false;
            this.presentToast(res.msg);
            this.router.navigate(['/login']);
          }else{
            loader.dismiss();
            this.disabledButton = false;
            this.presentToast(res.msg);
          }
        },(err)=>{
          loader.dismiss();
          this.disabledButton = false;
          this.presentAlert('Timeout');
        });
      });
    }
  }

  async presentToast(a){
    const toast = await this.toastCtrl.create({
      message : a,
      duration: 1500,
      position: 'top'
    });
    toast.present();
  }

  async presentAlert(a){
    const alert = await this.alertCtrl.create({
      header: a,
      backdropDismiss: false,
      buttons: [
      {
        text: 'Close',
        handler: (blah) => {
          console.log('Confirm Cancel: blah');
          //action
        }
      }, {
          text: 'Try Again',
          handler: () => {
            this.tryRegister();
          }
        }
      ]
    });
    await alert.present();
  }
}

access-providers.ts

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
import { map } from 'rxjs/operators';
import { timeout } from 'rxjs/operators'; 

@Injectable()
export class AccessProviders {
    //url backend api json
    server: string ='http://localhost/login-register-home/api/';

    constructor(public http: HttpClient){}

    postData(body, file){
        let headers = new HttpHeaders({
            'Content-Type' : 'application/json; charset=UTF-8'
        });
        let options = {
            headers: headers
        }

        return this.http.post(this.server + file,JSON.stringify(body), options)
        .pipe(timeout(59000))// 59 sec timeout
        .pipe(map(res => res));
    }
}

Does anyone how to fix this ? Thank you

As the error in your thread title says, when you try to bind something in the template, it must exist as a property of that page’s controller, so LoginPage needs a u_email_address property (which typical naming conventions would call something like emailAddress instead).

You also do not need to manually declare Content-Type or provide any custom headers or options here, and should not be manually stringifying body. Just this.http.post(this.server + file, body).

I have found the solution, some code lines is missed in login.page.ts

The error TS2339 is resolved, but the timeout error is still remain.
The timeout alert pop out but no log errors displayed. And the input data for register is saved in MYSQL database. I can’t really find errors in register.page.ts, can you help me on this ?