Injecting service not working


#1

I created something very basic and quick in a couple of minutes so it is easy to reproduce.

I created an app using:

ionic start blank --v2

then I create a provider:

ionic g provider FacebookFriends

I then put this code inside of on my provider:

import {Injectable, Inject} from 'angular2/core';
import {Http} from 'angular2/http';

/*
  Generated class for the FacebookFriends provider.

  See https://angular.io/docs/ts/latest/guide/dependency-injection.html
  for more info on providers and Angular 2 DI.
*/
@Injectable()
export class FacebookFriends {
  constructor(@Inject(Http) http) {
    this.http = http;
    this.data = null;
  }

  load() {
    if (this.data) {
      // already loaded data
      return Promise.resolve(this.data);
    }

    // don't have the data yet
    return new Promise(resolve => {
      // We're using Angular Http provider to request the data,
      // then on the response it'll map the JSON data to a parsed JS object.
      // Next we process the data and resolve the promise with the new data.
      this.http.get('path/to/data.json')
        .map(res => res.json())
        .subscribe(data => {
          // we've got back the raw data, now generate the core schedule data
          // and save the data for later reference
          this.data = data;
          resolve(this.data);
        });
    });
  }
}

I then try to inject this into app.js:

import {App, Platform} from 'ionic-angular';
import {TabsPage} from './pages/tabs/tabs';
import {FacebookFriends} from './providers/facebook-friends/facebook-friends';

@App({
  template: '<ion-nav [root]="rootPage"></ion-nav>',
  config: {}, // http://ionicframework.com/docs/v2/api/config/Config/,
  providers: [FacebookFriends]
})
export class MyApp {
  static get parameters() {
    return [[Platform]];
  }

  constructor(platform, private _facebookFriends) {
    this.rootPage = TabsPage;

    platform.ready().then(() => {
    });
      }
    }

This is all I did. When I run ionic serve I get many errors. I get that the there is an unknown token and it points at the @Inject and @Injectable words. I also get an unexpected token at the private _facebookFriends line.

Also if I try to add a types to the constructor so I would have platform:Platform and _facebookFriends:FacebookFriends I also get that the ‘:’ are unknown tokens.

I am essentially just trying to call a service from my app.js, but it is not working.


#2

That’s probably because those are TypeScript concepts, and you’re not working with a TypeScript project. So I would say your options are (a) use TypeScript and go that route, or (b) add FacebookFriends to MyApp's static parameters method.


#3

I would like to use typescript. How could I do this in ionic2? I have just been following their getting started guide to create the project?


#4

Pass the --ts option to the ionic start command that generates the project.


#5

So I ran the command:

ionic start testproject blank --v2 --ts

It created the project. I created the provider template again.

My provider code (which is still facebook-friends.js instead of a typescript extension not sure if this is the way it should be?):

import {Injectable, Inject} from 'angular2/core';
import {Http} from 'angular2/http';

/*
  Generated class for the FacebookFriends provider.

  See https://angular.io/docs/ts/latest/guide/dependency-injection.html
  for more info on providers and Angular 2 DI.
*/
@Injectable()
export class FacebookFriends {
  constructor(@Inject(Http) http) {
    this.http = http;
    this.data = null;
  }

  load() {
    if (this.data) {
      // already loaded data
      return Promise.resolve(this.data);
    }

    // don't have the data yet
    return new Promise(resolve => {
      // We're using Angular Http provider to request the data,
      // then on the response it'll map the JSON data to a parsed JS object.
      // Next we process the data and resolve the promise with the new data.
      this.http.get('path/to/data.json')
        .map(res => res.json())
        .subscribe(data => {
          // we've got back the raw data, now generate the core schedule data
          // and save the data for later reference
          this.data = data;
          resolve(this.data);
        });
    });
  }
}

my app.ts:

import {App, Platform} from 'ionic-angular';
import {HomePage} from './pages/home/home';
import {FacebookFriends} from './providers/facebook-friends/facebook-friends';

@App({
  template: '<ion-nav [root]="rootPage"></ion-nav>',
  config: {},
  providers: [FacebookFriends] 
})
export class MyApp {
  rootPage: any = HomePage;

  constructor(platform: Platform, private _fb: FacebookFriends) {
    platform.ready().then(() => {

    });
  }
}

I get the following error when I run ionic serve:

./app/providers/facebook-friends/facebook-friends.js
Module parse failed: /home/susan/testing/app/providers/facebook-friends/facebook-friends.js Line 1: Unexpected token
You may need an appropriate loader to handle this file type.
| import {Injectable, Inject} from 'angular2/core';
| import {Http} from 'angular2/http';
| 
 @ ./app/app.ts 13:25-81,[default] /home/susan/testing/app/app.ts:3:30 
Cannot find module './providers/facebook-friends/facebook-friends'.,[default] /home/susan/testing/node_modules/angular2/src/facade/promise.d.ts:1:9 
Cannot re-export name that is not defined in the module. (CLI v2.0.0-beta.19)

#6

That’s probably your problem. Try with a ‘.ts’ extension.


#7

Unfortunately currently there are no generators for TypeScript. This is a known issue - see ionic-cli issue #753. The only solution at the moment is to rename the file to .ts and convert it to TypeScript, i.e.:

import {Injectable} from 'angular2/core';
import {Http} from 'angular2/http';

/*
  Generated class for the FacebookFriends provider.

  See https://angular.io/docs/ts/latest/guide/dependency-injection.html
  for more info on providers and Angular 2 DI.
*/
@Injectable()
export class FacebookFriends {
  data: any = null;
  
  constructor(private http: Http) {
  }

  load() {
    if (this.data) {
      // already loaded data
      return Promise.resolve(this.data);
    }

    // don't have the data yet
    return new Promise(resolve => {
      // We're using Angular Http provider to request the data,
      // then on the response it'll map the JSON data to a parsed JS object.
      // Next we process the data and resolve the promise with the new data.
      this.http.get('path/to/data.json')
        .map(res => res.json())
        .subscribe(data => {
          // we've got back the raw data, now generate the core schedule data
          // and save the data for later reference
          this.data = data;
          resolve(this.data);
        });
    });
  }
}

#8

thank you so much for the information! I have tried to convert it now and it runs, but one error shows up stating:

ERROR in [default] /home/susan/testing/node_modules/angular2/src/facade/promise.d.ts:1:9
Cannot re-export name that is not defined in the module.

I googled the error and it is an error with Angular2. It is fixed, but since Ionic is delayed with the angular2 it is still not merged. There is a workaround which can be found here (Hope it helps someone): https://github.com/angular/angular/issues/6468


#9

You might recognize me from such places as “reporting that issue”. You should be able to update your package.json to something past angular beta 7 and everything should be copacetic.


#10

Thanks! I didn’t know I could do that!