5

Able to access the Google Picker only once in a while. Google Picker Popup doesn't opens every time when I open the application.

I'm implementing Google Picker API in Angular 6. I kept separate file for the logic behind connecting the Google API in the assets folder of angular and by the help of document.createElement("script"), appended the javascript file. And I have an Anchor tag to getElementById in app.component.html.

app.component.html

<a routerLink="/" id="AllFilePick" #AllFilePick> Button </a>

app.component.ts

    import { Component, ViewChild, ElementRef, OnInit } from '@angular/core';


    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.scss']
    })


    export class AppComponent implements OnInit {

      @ViewChild('AllFilePick') AllFilePick: ElementRef;

      constructor(private elementRef: ElementRef) { }


      ngOnInit() { 

        var s1 = document.createElement("script");
        s1.type = "text/javascript";
        s1.src = "../assets/api-script.js";
        this.elementRef.nativeElement.appendChild(s1);

        var s2 = document.createElement("script");
        s2.src = "https://www.google.com/jsapi?key=<API_KEY>";
        this.elementRef.nativeElement.appendChild(s2);

        var s3 = document.createElement("script");
        s3.src = "https://apis.google.com/js/client.js?onload=SetPicker";
        this.elementRef.nativeElement.appendChild(s3);

        // console.log(this.AllFilePick.nativeElement);
        console.log(s1);
        console.log(s2);
        console.log(s3);

      }
    }

I even tried using ngAfterViewInit, constructor for appending the script tag.

assets/api-script.js

    function SetPicker() {
        var picker = new FilePicker(
            {
                apiKey: ‘<API_KEY>’, 
                clientId: ‘<CLIENT_ID>’,
                buttonEl: document.getElementById("AllFilePick"),
                onClick: function (file) {             
                    PopupCenter('https://drive.google.com/file/d/' + file.id + '/view', "", 1026, 500);
                }
            }
        );
    }

    function PopupCenter(url, title, w, h)
    {
       //.....
    }

    function FilePicker(User)
    {
        //Configuration 
        //....
    }

The Above full version code runs properly but pop-up opens rarely, once in a while. Pop up triggers only after refreshing the application for several times or Opening the application next day. Picker doesn't works regularly in the Angular.

Arun S
  • 51
  • 1
  • 5

3 Answers3

6

In index.html

 <script type="text/javascript" src="https://apis.google.com/js/api.js"></script>
  <script src="https://apis.google.com/js/platform.js"></script>

In component template (.html) file.

<button (click)="loadGoogleDrive()"><G-Drive</button>
In Component (.ts file).

import { Component } from '@angular/core';
declare var gapi: any;
declare var google: any;

@Component({
  selector: 'app-selector',
  templateUrl: './app-selector.component.html',
  styleUrls: ['./app-selector.component.css']
})
export class GoogleDriveSelectorComponent {

  developerKey = 'developer/API key here';
  clientId = "client_id"
  scope = [
    'profile',
    'email',
    'https://www.googleapis.com/auth/drive'//insert scope here
  ].join(' ');
  pickerApiLoaded = false;
  oauthToken?: any;

  loadGoogleDrive() {
    gapi.load('auth', { 'callback': this.onAuthApiLoad.bind(this) });
    gapi.load('picker', { 'callback': this.onPickerApiLoad.bind(this) });
  }

  onAuthApiLoad() {
    gapi.auth.authorize(
      {
        'client_id': this.clientId,
        'scope': this.scope,
        'immediate': false
      },
      this.handleAuthResult);
  }

  onPickerApiLoad() {
    this.pickerApiLoaded = true;
  }

  handleAuthResult(authResult) {
    let src;
    if (authResult && !authResult.error) {
      if (authResult.access_token) {
        let view = new google.picker.View(google.picker.ViewId.DOCS);
        view.setMimeTypes("image/png,image/jpeg,image/jpg,video/mp4");
        let pickerBuilder = new google.picker.PickerBuilder();
        let picker = pickerBuilder.
          enableFeature(google.picker.Feature.NAV_HIDDEN).
          setOAuthToken(authResult.access_token).
          addView(view).
          addView(new google.picker.DocsUploadView()).
          setCallback(function (e) {
            if (e[google.picker.Response.ACTION] == google.picker.Action.PICKED) {
              let doc = e[google.picker.Response.DOCUMENTS][0];
              src = doc[google.picker.Document.URL];
              console.log("Document selected is", doc,"and URL is ",src)
            }
          }).
          build();
        picker.setVisible(true);
      }
    }
  }

}
Atif Zia
  • 777
  • 2
  • 11
  • 28
  • Essential! To get started using Google Picker API, you need to first use the setup tool https://console.developers.google.com/start/api?id=picker&credential=client_key Read more at the doc https://developers.google.com/drive/picker/guides/overview – Serhii Polishchuk Apr 24 '22 at 15:21
1

In Index.html

<script type="text/javascript" src="https://apis.google.com/js/api.js?onload=loadPicker"></script>

Create a Service like googleDrivePickerService (.service.ts)

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

declare const gapi: any;
declare const google: any;

@Injectable({
  providedIn: 'root'
})
export class GoogleDrivePickerService {

  private clientId = 'YOUR_CLIEND_ID';
  private apiKey = 'YOUR_API_KEY';
  private appId = 'YOUR_APP_ID';
  private scope = 'https://www.googleapis.com/auth/drive.file',

  private oauthAccessToken = null;
  private pickerApiLoaded = false;
  private pickerCallback = null;

  public open(callback): void {
    this.pickerCallback = callback;
    gapi.load('auth', {'callback': this.onAuthApiLoad.bind(this)});
    gapi.load('picker', {'callback': this.onPickerApiLoad.bind(this)});
  }

  private onAuthApiLoad(): void {
    gapi.auth.authorize({
      'client_id': this.clientId,
      'scope': this.scope,
      'immediate': false,
    }, this.handleAuthResult.bind(this));
  }

  private onPickerApiLoad(): void {
    this.pickerApiLoaded = true;
    this.createPicker();
  }

  private handleAuthResult(authResult): void {
    if (authResult && !authResult.error) {
      this.oauthAccessToken = authResult.access_token;
      this.createPicker();
    }
  }

  private createPicker(): void {
    if (this.pickerApiLoaded && this.oauthAccessToken) {
      let view = new google.picker.View(google.picker.ViewId.DOCS);
      let picker = new google.picker.PickerBuilder()
        .enableFeature(google.picker.Feature.NAV_HIDDEN)
        .enableFeature(google.picker.Feature.MULTISELECT_ENABLED)
        .setAppId(this.appId)
        .setOAuthToken(this.oauthAccessToken)
        .addView(view)
        .addView(new google.picker.DocsUploadView())
        .setDeveloperKey(this.apiKey)
        .setCallback(this.pickerCallback)
        .build();
      picker.setVisible(true);
    }
  }
}

In your Component (.ts), Import the service and add in the constructor then finally call the open function with a callback.

import {GoogleDrivePickerService} from '../services/googledrivepicker.service';

constructor(
  private googleDrivePickerService: GoogleDrivePickerService
){}

openGoogleDrivePicker(): void {
  this.googleDrivePickerService.open((data) => {
    if (data.action === 'picked') {
      console.log('Picked', data.docs);
    }
  });
}
b1617
  • 162
  • 1
  • 2
  • 8
  • 1
    Best way to authorize at the time of google login, and then after whenever we need a file just picking from picker dialog. – Alam Jun 20 '21 at 21:02
-1

click here How to implement SignIn with Google in Angular 2 using Typescript and just create index.html in your app folder u will 100% solve this problem bcoz same problem was with me.

Sid
  • 1
  • 1
  • 1
    If you think this is a duplicate question of the question you gave the link for, please use FLAG button to mark it as a duplicate. – sertsedat Aug 09 '18 at 12:42