Akanksha Akanksha - 2 months ago 49
TypeScript Question

Google API Endpoints using Javascript client library as an Angular 2 Service

I am using Google API Javascript library in my Angular 2 application. I have created a service which is injected in components. Here is the code:

import { Injectable } from '@angular/core';
const url = 'https://apis.google.com/js/client.js?onload=__onGoogleLoaded';
@Injectable()
export class GoogleAPIService {
public client: any;
public calculatorService: any;
public actionService: any;
loadAPI: Promise<any>
constructor(){
this.loadAPI = new Promise((resolve) => {
window['__onGoogleLoaded'] = (ev) => {
console.log('gapi loaded');
resolve(window['gapi']);
this.client = window['gapi'].client;
this.loadEndPoints('{Endpoint URL}/_ah/api');
}
this.loadScript();
});

}

doSomethingGoogley(){
return this.loadAPI.then((gapi) => {
console.log(gapi);
});
}

loadScript(){
console.log('loading..')
let node = document.createElement('script');
node.src = url;
node.type = 'text/javascript';
document.getElementsByTagName('head')[0].appendChild(node);

}

loadEndPoints(apiRoot) {
// Loads the OAuth and calculatorendpoint APIs asynchronously, and triggers login
// when they have completed.
var apisToLoad;
var callback = function() {
console.log('API Loaded '+apisToLoad);
if (--apisToLoad == 0) {
//this.endpoint1= this.client.endpoint1; //Doesn't Work
//this.endpoint2= this.client.endpoint2;
}

}

apisToLoad = 3; // must match number of calls to gapi.client.load()
this.client.load('oauth2', 'v2', callback);
this.client.load('endpoint1', 'v1', callback, apiRoot);
this.client.load('endpoint2','v1',callback,apiRoot);

}
}


I have three questions:


  1. How do I get the endpoints gapi.client.endpoint1 as a public variable in the service?

  2. How do I call the methods in the api? In javascript, u can jst call gapi.client.endpoint1.method().execute()

  3. How do I make this service singleton?



Any help is appreciated.

Answer

Services are singletons by default. You should provide it in your AppModule, and then it will be available to all of your components. Just make sure to include it in your component constructors.

import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {HttpModule} from '@angular/http';

import { AppComponent } from './app.component';
import { routing } from './app.routing'; 
import { GoogleService } from './google.service'; // important

@NgModule({
    imports: [
        BrowserModule,
        HttpModule,
        routing,
    ],
    declarations: [ AppComponent],
    providers: [ GoogleService ], // important
    bootstrap: [ AppComponent],
})
export class  AppModule {
}

To make an endpoint available outside of your service, you can use the public keyword in front of the function that calls the endpoint. To call the endpoint in angular2, you can use the built-in http service from @angular/http. Here's an example service (only using HTTP GET) that will return an Observable for the endpoints you call.

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs';

@Injectable()
export class GoogleService {

    constructor(private http: Http) { }

    public endpoint1(): Observable<any> {
        return this.http.get("http://endpoint.one.com");
    }

    public endpoint2(): Observable<any> {
        return this.http.get("http://endpoint.two.com");
    }

}

You can then use the service like this in your component.

import { Component, OnInit } from '@angular/core';
import { GoogleService } from './google.service'; // important

@Component({
    selector: 'app',
    templateUrl: 'app.component.html'
})
export class AppComponent implements OnInit {
    constructor(private googleService: GoogleService) { }

    ngOnInit() {

        this.googleService.endpoint1().subscribe(callback1, handleError);

        this.googleService.endpoint2().subscribe(callback2, handleError);

    }

    callback1(data){
        // do something with the data from ONE
    }

    callback2(data){
        // do something with the data from TWO
    }

    handleError(error: any){
        console.error(error);
    }

}

I recommend reading up a bit on using Observables in this post from Angular University.