[SOLVED] Help using 3rd party Javascript or Node module with Ionic2


#1

Hi all, I’m trying to use the Soundcloud Javascript SDK and running into problems. It seems I could try it both of these ways, which aren’t working:

  1. With script tag:

This works in my index.html, but the SC variable is not accessible in any other pages.

  1. With npm:

    var SC = require(‘soundcloud’);

    SC.initialize({
    client_id: ‘YOUR_CLIENT_ID’,
    redirect_uri: ‘http://example.com/callback
    });

As written, it does not compile, I believe because this isn’t how you load things with TypeScript. However, I changed to use import and created a new index.d.ts file for the soundcloud module, and this allowed compilation to pass. However, nothing after the initialize function is executed, which makes me think I’m doing something wrong with my TypeScript (unsurprising since I just hacked something).

I’m fine with either way, as long as it works :slight_smile: Thanks!

shawn.


#2

I think #2 is the better choice, but it would help to see your typings file.


#3

Ok, here’s the file I created, named index.d.ts. I simply placed it in the node_modules/soundcloud directory and added "typings": "./index.d.ts", into package.json. If there’s anything else I need to do, please let me know as I don’t have experience with this. Specifically I see files index.js.map, but if that has to be generated, I don’t know how.

export declare class SC {
  static initialize(options: SCOptions);

  static stream(trackPath: string, secretToken?: string): Promise<Player>;

  static get(path: string, params?: any): Promise<any>;
}

export interface SCOptions {
  client_id: string;
  redirect_uri?: string;
  oauth_token?: string;
}

export declare class Player {
  play();
  pause();
}

Also, I put static on only the methods which allowed me to have no compile failures; I can’t tell why they’re needed some places and not others.


#4

I don’t have access tokens which are probably needed to really run the thing, but I can at least get the functions to resolve properly by modifying your typings thusly:

export interface SoundCloud {
  initialize(options: SCOptions);
  stream(trackPath: string, secretToken?: string): Promise<Player>;
  get(path: string, params?: any): Promise<any>;
}

export declare var SC:SoundCloud;
import * as soundcloud from 'soundcloud';

soundcloud.initialize({...});

#5

Yeah, that gives me compile failures:
Property ‘initialize’ does not exist on type ‘typeof “/Users/Admin/dev/Ionic/Yogini/node_modules/soundcloud/index”’.

But if I make a couple other improvements based on what you suggested, I still get the same error (doesn’t get past the initialization call). Here’s my code with the client_id so you can try it:

export interface SoundCloud {
  initialize(options: SCOptions);

  stream(trackPath: string, secretToken?: string): Promise<Player>;

  get(path: string, params?: any): Promise<any>;
}
export declare var SC: SoundCloud;

import { SC } from 'soundcloud';
...
SC.initialize({
  client_id: '69e382c16c5478ccb5ea223a0e1c4c92'
});
console.log('You won't see me');

#6

Update: Even though I don’t get any errors during transcribing, it looks like it can’t find SC. Stepping through the debugger, attempting to call SC.initialize immediately throws an exception: "Cannot read property 'initialize' of undefined".


#7

typings:

interface SCOptions {
  client_id: string;
  redirect_uri?: string;
  oauth_token?: string;
}

interface SoundCloud {
  initialize(options: SCOptions): void;
  stream(trackPath: string, secretToken?: string): Promise<Player>;
  get(path: string, params?: any): Promise<any>;
}

interface Player {
  play();
  pause();
}

declare var SC:SoundCloud;
export = SC;

in the app constructor:

    platform.ready().then(() => {
      // Okay, so the platform is ready and our plugins are available.
      // Here you can do any higher level native things you might need.
      StatusBar.styleDefault();

      soundcloud.initialize({
        client_id: '69e382c16c5478ccb5ea223a0e1c4c92'
      });
      console.log("You won't see me");
    });

Console does indeed log “You won’t see me”.


#8

Success for me too! It seems like something wasn’t quite correct in the d.ts file, but now everything is looking good.

Interesting, but I just figured out how to do it the other way. If I include the SoundCloud JS file inside the <script> element, declaring the var on my ts page allows me to access it:

declare var SC: any;

Thanks for the help!!!


#9

Glad you got it working. I suppose it’s a philosophical argument, and I feel less strongly about it than I do about other things, but I prefer to not pollute index.html with a bunch of script tags. I like to let bundlers (Ionic prefers browserify, I prefer webpack) handle all that.


#10

Oh, me too, which is why I was keen to do it the proper way. It just so happens that I was successful BOTH ways, which means I’ll do the proper way. Already adding the typings to the type registry.