Получение следующей ошибки при отображении информации пользователя на странице в Angular и Ionic с Promise - PullRequest
0 голосов
/ 04 января 2019

В моем приложении и на AccountSettingsPage я извлекаю данные пользователя из SQLite DB и отображаю их на странице Ionic.Однако я получаю эту ошибку.

Ошибка:

TypeError: Cannot read property 'name' of undefined
    at Object.eval [as updateRenderer] (ng:///AppModule/AccountSettingsPage.ngfactory.js:87:37)
    at Object.debugUpdateRenderer [as updateRenderer] (http://192.168.0.4:8100/build/vendor.js:15109:21)
    at checkAndUpdateView (http://192.168.0.4:8100/build/vendor.js:14223:14)
    at callViewAction (http://192.168.0.4:8100/build/vendor.js:14569:21)
    at execComponentViewsAction (http://192.168.0.4:8100/build/vendor.js:14501:13)
    at checkAndUpdateView (http://192.168.0.4:8100/build/vendor.js:14224:5)
    at callViewAction (http://192.168.0.4:8100/build/vendor.js:14569:21)
    at execEmbeddedViewsAction (http://192.168.0.4:8100/build/vendor.js:14527:17)
    at checkAndUpdateView (http://192.168.0.4:8100/build/vendor.js:14219:5)
    at callViewAction (http://192.168.0.4:8100/build/vendor.js:14569:21)

account-settings.ts

export class AccountSettingsPage {

  currentUser: User;

  constructor(private navCtrl: NavController, private navParams: NavParams, private userProvider: UserProvider) {
    this.getCurrentUserDetails("ab@cd.com");
  }

  getCurrentUserDetails(email: string) {
    this.userProvider.getUserByEmail(email)
      .then((currentUser: User) => {
        this.currentUser = currentUser;
        console.log("data: " + JSON.stringify(currentUser));
      })
      .catch(e => console.error(JSON.stringify(e)));
  }

}   

user.ts (UserProvider)

getUserByEmail(email: string): Promise<User> {
    return this.databaseProvider.getDatabase().then(database => {
      return database.executeSql(SQL_SELECT_USER_BY_EMAIL, [email])
        .then((data) => {
          let user: User;
          //loop through all the records and populate the user object. Should be only 1
          for (let i = 0; i < data.rows.length; i++) {
            user = {
              id: data.rows.item(i).id,
              name: data.rows.item(i).name,
              email: data.rows.item(i).email,
              password: data.rows.item(i).password,
              confirmPassword: data.rows.item(i).password,
              phone: data.rows.item(i).phone,
              street1: data.rows.item(i).street1,
              street2: data.rows.item(i).street2,
              city: data.rows.item(i).city,
              state: data.rows.item(i).state,
              zip: data.rows.item(i).zip,
              active: data.rows.item(i).active
            };
          }
          //return the populated user object back
          return user;
        });

    });
  }

account-settings.html (Page)

<ion-header>
  <ion-navbar>
    <ion-title>Account Settings</ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>
  <ion-list>
    <ion-label>Name: {{currentUser.name}}</ion-label>
    <ion-label>Email: {{currentUser.email}}</ion-label>
    <ion-label>Password: {{"*****"}}</ion-label>
    <ion-label>Phone: {{currentUser.name}}</ion-label>
    <ion-label>Street 1: {{currentUser.street1}}</ion-label>
    <ion-label>Street 2: {{currentUser.street1}}</ion-label>
    <ion-label>City: {{currentUser.city}}</ion-label>
    <ion-label>State: {{currentUser.state}}</ion-label>
    <ion-label>Zip: {{currentUser.zip}}</ion-label>
  </ion-list>
  <button ion-button (click)="logout()">Logout</button>
</ion-content>

Ответы [ 2 ]

0 голосов
/ 04 января 2019

При создании вашего представления ваш currentUser в вашем контроллере равен undefined, пока он не извлечен из базы данных.

Вы должны добавить директиву * ngIf в ваш HTML, чтобы предотвратить отображениеесли currentUser не определено.

<ion-content *ngIf="currentUser" padding>
  <ion-list>
    <ion-label>Name: {{currentUser.name}}</ion-label>
    <!-- ... -->
  </ion-list>
  <button ion-button (click)="logout()">Logout</button>
</ion-content>

Затем обновите UserProdiver , чтобы фактически вернуть значение из обещания:

getUserByEmail(email: string): Promise<User> {
  return new Promise((resolve, reject) => {
    this.databaseProvider.getDatabase().then(database => {
      database.executeSql(SQL_SELECT_USER_BY_EMAIL, [email])
        .then((data) => {
          let user: User;
          //loop through all the records and populate the user object. Should be only 1
          for (let i = 0; i < data.rows.length; i++) {
            user = {
              id: data.rows.item(i).id,
              name: data.rows.item(i).name,
              email: data.rows.item(i).email,
              password: data.rows.item(i).password,
              confirmPassword: data.rows.item(i).password,
              phone: data.rows.item(i).phone,
              street1: data.rows.item(i).street1,
              street2: data.rows.item(i).street2,
              city: data.rows.item(i).city,
              state: data.rows.item(i).state,
              zip: data.rows.item(i).zip,
              active: data.rows.item(i).active
            };
          }
          //return the populated user object back
          return resolve(user);
        });
    });
  });
}
0 голосов
/ 04 января 2019

Попробуйте использовать * ngIf , чтобы отображать данные пользователя только после успешной загрузки currentUser.Поскольку currentUser не инициализируется со значениями по умолчанию для всех этих свойств, которые вы отображаете и загружаете асинхронно, вы можете использовать эту структурную директиву, чтобы не пытаться получить доступ к этим свойствам неопределенного объекта до тех пор, пока он не будет успешно загружен / разрешен:

<ion-content *ngIf=“currentUser” padding>
  <ion-list>
    <ion-label>Name: {{currentUser.name}}</ion-label>
    <ion-label>Email: {{currentUser.email}}</ion-label>
    <ion-label>Password: {{"*****"}}</ion-label>
    <ion-label>Phone: {{currentUser.name}}</ion-label>
    <ion-label>Street 1: {{currentUser.street1}}</ion-label>
    <ion-label>Street 2: {{currentUser.street1}}</ion-label>
    <ion-label>City: {{currentUser.city}}</ion-label>
    <ion-label>State: {{currentUser.state}}</ion-label>
    <ion-label>Zip: {{currentUser.zip}}</ion-label>
  </ion-list>
  <button ion-button (click)="logout()">Logout</button>
</ion-content>

Вы можете расширить эту концепцию, используя оператор else с *ngIf, чтобы, возможно, показать загрузочное сообщение или подобное во время загрузки данных:

<ion-content *ngIf=“currentUser; else loadingCurrentUser” padding>
  <ion-list>
    <ion-label>Name: {{currentUser.name}}</ion-label>
    <ion-label>Email: {{currentUser.email}}</ion-label>
    <ion-label>Password: {{"*****"}}</ion-label>
    <ion-label>Phone: {{currentUser.name}}</ion-label>
    <ion-label>Street 1: {{currentUser.street1}}</ion-label>
    <ion-label>Street 2: {{currentUser.street1}}</ion-label>
    <ion-label>City: {{currentUser.city}}</ion-label>
    <ion-label>State: {{currentUser.state}}</ion-label>
    <ion-label>Zip: {{currentUser.zip}}</ion-label>
  </ion-list>
  <button ion-button (click)="logout()">Logout</button>
</ion-content>

<ng-template #loadingCurrentUser>
  Loading...
</ng-template>

Наконец, рассмотрите возможность выполнения этого вызовав ловушке Angular жизненного цикла OnInit вместо конструктора это идеальное место для задач инициализации, таких как вызов базы данных:

export class AccountSettingsPage implements OnInit {
  currentUser: User;

  constructor(private navCtrl: NavController, private navParams: NavParams, private userProvider: UserProvider) {}

  ngOnInit(): void {
    this.getCurrentUserDetails("ab@cd.com");
  }

  getCurrentUserDetails(email: string) {
    this.userProvider.getUserByEmail(email)
      .then((currentUser: User) => {
        this.currentUser = currentUser;
        console.log("data: " + JSON.stringify(currentUser));
      })
      .catch(e => console.error(JSON.stringify(e)));
  }
}

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...