1

I have an angular 4 service which uses an external JavaScript file, I need to pass an function as argument for one of the JavaScript function like JavascriptAPI.setMessageHandler(this.onMessage.bind(this)) JavascriptAPI.setStatusHandler(this.onStatus.bind(this)).

When i run this, I'm getting following error polyfills.bundle.js:2610 Uncaught TypeError: JavascriptAPI.be is not a function at WebSocket.e2.onopen (eval at webpackJsonp.../../../../script-loader/addScript.js.module.exports (scripts.bundle.js:28), :69:404) at WebSocket.wrapFn [as __zone_symbol___onopen] (polyfills.bundle.js:3484) at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (polyfills.bundle.js:2839) at Zone.webpackJsonp.../../../../zone.js/dist/zone.js.Zone.runTask (polyfills.bundle.js:2606) at ZoneTask.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (polyfills.bundle.js:2913) at invokeTask (polyfills.bundle.js:3779) at WebSocket.globalZoneAwareCallback (polyfills.bundle.js:3797)

import { Injectable } from '@angular/core'

declare var JavascriptAPI: any;

@Injectable()
export class SampleService  {

     constructor() { }

      onMessage(messages) {
        console.log('onMessage', messages)
      }

      onStatus(messages) {
        console.log('onStatus', messages)
      }

      onInit(token: string) {
        JavascriptAPI.disconnect()
        JavascriptAPI.setConnect(token)
        const serverUrl = ['http://localhost:8080']
        JavascriptAPI.setServers(serverUrl)
        JavascriptAPI.setMessageHandler(this.onMessage.bind(this))
        JavascriptAPI.setStatusHandler(this.onStatus.bind(this))
      }
  }

Thanks, Appreciate for your time.

6
  • there's not enough info your example to tell you how to fix it, but it looks like you need to find out where your JavascriptAPI lives in the global namespace and assign it to that variable. So if there were a window.JavascriptAPI object, you'd write something like this: declare var JavascriptAPI: any = window.JavascriptAPI. Don't know where that code lives, but that's the basic concept. Usually I'll just set a breakpoint when I run into these issues and inspect what's going on in the window object to find out how to reference the code Commented Jul 28, 2017 at 21:25
  • Thanks for your quick response, I would like to know the way i'm passing the typescript method onMessage as an function to the JavascriptAPI.setMessageHandler() function is correct/wrong ? Is this correct approach ? webpack is complaining that onMessage is not a function. Commented Jul 28, 2017 at 22:13
  • I'll give you some more hints, but I'll put it in an answer below because there's not enough space here. Commented Jul 28, 2017 at 22:25
  • I'm not sure if you understood my question or my understanding on your answer is correct, I don't have any problem in accessing the JavaScriptAPI. I'm able to access the JavaScriptAPI, the following codes are all complied properly by webpack, JavascriptAPI.disconnect() JavascriptAPI.setConnect(token) const serverUrl = ['localhost:8080'] JavascriptAPI.setServers(serverUrl) when it comes to JavascriptAPI.setMessageHandler(this.onMessage.bind(this)), the webpack complains this.onMessage.bind(this) is not a function Commented Jul 30, 2017 at 17:39
  • I need to know, how to pass a typescript class method/function (as a callback function) to this setMessageHandler function of JavascriptAPI Commented Jul 30, 2017 at 17:40

1 Answer 1

1

So you've got this javascript functionality that lives outside the namespace for your typescript, 'Javascript API'.

Let's say the script for JavascriptAPI looks like this :

<script>
var JavascriptAPI = function(){
   return {
       disconnect: function() {},
       setConnect: function(token),
       // more functions 
       }
}
</script>

When you run that script, it will create a variable inside the global namespace which can be accessed via the window object. Try removing the 'script' tags and running it in your console.

While you're in the console, there are two ways you can access that variable now. You can type 'JavascriptAPI' and not surprisingly you will see the function returned. It's the second way that concerns us more. Try typing 'window.JavascriptAPI' in the console. You'll see the same value. That's the variable you want to point to in your component when you declare the variable.

Now this is just a hypothetical implementation of your JavascriptAPI function. But the point is you want to figure out where it lives in the namespace of your application once it's all running. So if it works like this example

declare var JavascriptAPI: any = window.JavascriptAPI;

Typescript might throw an error/warning saying that property JavascriptAPI doesn't exist on type window. There may be better ways to work around the error if it pops up, but here's one way you could do it.

  var windowCopy = window as any;
declare var JavascriptAPI: any = windowCopy.JavascriptAPI;

In other words, you might want to use the second piece of code to not get warnings using typescript, but the concept is the same.

If you can't figure out how to reference the 'JavascriptAPI' based on looking at it's code, try putting a breakpoint in somewhere and looking at the window object to see where it lives there, and reference that.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.