2

I am trying to retrieve contacts from Google within an Angular 4 Universal app.

But I receive this error message once authentication has been done:

Refused to execute script from https://www.google.com/m8/feeds/contacts/default/full?access_token=TOKEN&alt=json because its MIME type ('application/json') is not executable, and strict MIME type checking is enabled.

At the moment everything is held in one Component:

import { Component, OnInit } from '@angular/core';
import { Jsonp } from '@angular/http';

@Component({
  selector: 'refer-friend',
  templateUrl: './referFriend.component.html',
})
export class ContactsComponent implements OnInit {
  constructor(private jsonp: Jsonp) { }
  ngOnInit(): void {
    this.auth();
  }
  auth() {
    gapi.auth.authorize({
      'client_id': 'CLIENTID.apps.googleusercontent.com',
      'scope': 'https://www.google.com/m8/feeds'
    }, () => {
      this.fetch(gapi.auth.getToken());  
    });
  }
  fetch(token: any) {
    this.jsonp.get('https://www.google.com/m8/feeds/contacts/default/full?access_token=' + token.access_token + '&alt=json')
     .map(data => {
        return data;
     })
     .subscribe(data => {
         console.log(data);
     });
  }
}

I got the code from this sample which works fine without this error happening. So I can only guess Angular is effecting something....

JGFMK
  • 8,425
  • 4
  • 58
  • 92
Michael Wilson
  • 1,548
  • 3
  • 21
  • 44
  • Are you sure it's not a duplicate of this? https://stackoverflow.com/questions/36289495/how-to-make-a-simple-jsonp-asynchronous-request-in-angular-2 – JGFMK Jul 19 '17 at 15:53
  • 1
    You would not return data in a map either. It's usually used to do things like convert a Response https://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html to a json payload - Response contains HTTP headers etc. so map(response:Response => responce.json()). You should also refactor that into a service an return it as an Observable. Ideally of an interface or domain model class. I see you're subscribing to a feed. The component should then inject that service annotated with @ Injectable as a private param in the component constructor, & be wired into @ ngModule providers:[] of your app-module.ts – JGFMK Jul 19 '17 at 16:17
  • then the component becomes... this.service.subscribe(data => this.data = data); – JGFMK Jul 19 '17 at 16:17
  • 1
    I was trying to determine the payload from here https://developers.google.com/google-apps/contacts/v3/ - FYI when you define an interface you can use ? to represent optional properties. See here https://www.typescriptlang.org/docs/handbook/interfaces.html – JGFMK Jul 19 '17 at 16:23

1 Answers1

2

The Google Contacts API documentation has a link to how the alt tag works. The value 'json' does not indicate that it will return JSONP data. Google returns that MIME type because the data it will give you is not executable.

https://developers.google.com/gdata/docs/2.0/reference

Try using the @angular/http standard get method instead of Jsonp.

nickrak
  • 1,635
  • 15
  • 18
  • You were right, thank you! I guess I got confused with the example I based it on because that was using JSONP for the AJAX call. – Michael Wilson Jul 24 '17 at 10:02