0

I am trying to create a shared User data provider:

import {Injectable} from '@angular/core';


@Injectable()

export class User {

  public name: string;
  public email: string;
  public password: string;
  public birthday: string;
  public settings: Settings;
  public loggedIn: boolean;

  constructor({
                name = null, email = null, password = null, birthday = null,
                settings = new Settings(),loggedIn = false
              }: {
    name?: string; email?: string; password?: string; birthday?: string;
     settings?: Settings; loggedIn?: boolean;
  } = {}) {

    this.name = name;
    this.email = email;
    this.password = password;
    this.birthday = birthday;
    this.settings = settings;
    this.loggedIn = loggedIn;
  }

  /**
   * @returns {number} the user's age.
   */
  get age(): number {
    let age = Math.abs(Date.now() - new Date(this.birthday).getTime());
    return Math.floor(age * 3.16887646E-11);
  }

}

@Injectable()
export class Settings {
  notificationSettings: NotificationSettings;
  preferencesSettings: PreferencesSettings;

  constructor({
                notificationSettings = new NotificationSettings(),
                preferencesSettings = new PreferencesSettings()
              }: {
    notificationSettings?: NotificationSettings;
    preferencesSettings?: PreferencesSettings;
  } = {}) {

    this.notificationSettings = notificationSettings;
    this.preferencesSettings = preferencesSettings;
  }
}

@Injectable()
export class NotificationSettings {
  // TODO
}

@Injectable()
export class PreferencesSettings {
  // TODO
}

At the app component, I am declaring the provider, in order to make a user globally available.

When I am trying to build the project, I get a Can't resolve all parameters for User: (?) error.

The problem occurs because of the settings in the User constructor, but I am having a difficulty to find the error in my logic.

Graham
  • 7,431
  • 18
  • 59
  • 84
Manos
  • 149
  • 1
  • 12

1 Answers1

2

I'm not sure of the exact scenario, but the problem with your code is that you need to know that one thing is a shared service, and another thing is a model that will be used in that service (and probably in some other services as well).

Models should not be injectables, they are just classes. Only services should. So in your case, we can start by creating the models of your app, and then we can add an AccountService to hold the instance of the user.

I've changed the name of the classes used as models just to avoid confusion (I think it's easier to know that something is a model if the name ends with -Model)

import { Injectable } from '@angular/core';

export class NotificationSettingsModel {
  // TODO
}

export class PreferencesSettingsModel {
  // TODO
}

export class SettingsModel {
  public notificationSettings: NotificationSettingsModel;
  public preferencesSettings: PreferencesSettingsModel;

  constructor() {
    this.notificationSettings = new NotificationSettingsModel();
    this.preferencesSettings = new PreferencesSettingsModel();
  }
}

export class UserModel {
    public name: string;
    public email: string;
    public password: string;
    public birthday: string;
    public settings: SettingsModel;

    constructor() {
        this.name = null;
        this.email = null;
        this.password = null;
        this.birthday = null;
        this.settings = new SettingsModel();
    }

    /**
    * @returns {number} the user's age.
    */
    get age(): number {
        let age = Math.abs(Date.now() - new Date(this.birthday).getTime());
        return Math.floor(age * 3.16887646E-11);
    }
}


@Injectable()
export class AccountService {

    public currentUser: UserModel = null;
    constructor() {}

    public isLoggedIn(): boolean {
        return this.currentUser !== null;
    }

}

After this, you'll need to add the AccountService in your main app module (or shared module). So for instance, you can add it in the app.module.ts file:

@NgModule({
  declarations: [...],
  imports: [...],
  bootstrap: [IonicApp],
  entryComponents: [...],
  providers: [AccountService] // <- Here!
})
export class AppModule { }

Then in your pages, just inject it and use it:

// imports...

@Component({...})
export class HomePage{

    constructor(public accountService: AccountService) {}

    public someMethod(): void {
      // You can access the properties
      // this.accountService.currentUser;

      // And also the methods: 
      // this.accountService.isLoggedIn();
    }

}
sebaferreras
  • 44,206
  • 11
  • 116
  • 134