Using Non-Ember libraries with ember-inject-script

Published on Sep 21, 2016

Writing Ember code and using Ember addons is great... but what if you need something from outside the Ember world?

There are challenges, but here are my 3 biggest tips:

  • Isolate in a component or service
  • Pull in library with ember-inject-script
  • Don't feel bad about using the library's (non-Ember) paradigms, as long as it stays isolated

UPDATE: code has since been updated, adding an else statement to the init function that also calls updateVideo. This helps it better deal with multiple uses of the components on one page. Jakub Olek has some great thoughts on that in the comments section below.


Links

Code

import Ember from 'ember';
import injectScript from 'ember-inject-script';

export default Ember.Component.extend({
  init(){
    this._super(...arguments);

    window._wq = window._wq || [];

    var scriptIsLoaded = $("script[src='//fast.wistia.com/assets/external/E-v1.js']")[0]
    if(!scriptIsLoaded){
      injectScript("//fast.wistia.com/assets/external/E-v1.js").then(()=>{
        this.updateVideo();
      })
    } else {
      this.updateVideo();
    }
  },
  //...
})

Transcript

Ember works great as long as you have ember-friendly codes, such as stuff you create yourself within ember, or stuff that you find in ember addons. But what if what you’re trying to do doesn’t have an addon and you have to use an outside library? Well, it’s not ideal, but there are some things we can do to contain the damage.

The first thing we want to do is to isolate it as much as possible, usually either within a component or a service. Because these are relatively isolated, you don’t have to worry in the rest of your code about what’s happening and how we’re getting the wistia-video. You just need to know that you call that component and stuff will play.

Second is using the ember-inject-script addon. So you install the addon and then you import the injectScript function, and then you can call injectScript with the url of that script. We have to do this because script tags in our handlebars don’t work. injectScript is great at injecting scripts, but it doesn’t necessarily notice whether you’ve already injected that script before. So one thing I’ve done here is to check if the script has loaded using jqueries, so it’s searching for scripts with this exact source, and if there’s one of them then we no longer inject the script. Anyways, injectScript returns a promise, and in that promise you can do whatever you want. Here we’re calling the updateVideo method.

So after you’ve injected this script, you’ll need to be working with the library that you just injected. And it won’t necessarily be ember-friendly. The way that you’re writing things won’t be what you’re used to. So for example here in updateVideo, it’s a normal method, but it’s also an observer. You’ve probably heard that observers are bad, but in this case this is the best way to get done what we need to get done, which is to when something changes within ember, to trigger this library and make sure that stuff happens when it’s supposed to. And more than just observers in particular, in general get ready for some weird stuff that goes against ember conventions. So for example this onReady block in a hash, in a push to something on the window, that’s what you have to do to get this library working, so that’s what you do. It doesn’t matter that it’s bad ember.

Same here with adding and removing video. So to get this particular library a trigger, you have to add in a new div with a certain code, and then it’ll do stuff based on that. So if you just change out this code, the library won’t trigger. So you have to replace your entire html block. That’s the sort of weird thing that you’re going to have to be prepared for. Also be prepared for lots of binding. So this is an event, you bind it there, and then there’s a callback of what you want to do once this event triggers.

So to review this episode, sometimes you can’t find the ember addon that you want, so you have to use weird JavaScript APIs. But you can contain the damage by putting them in a component or a service, and then you can use the ember injectScript addon to inject those libraries. And then the rest of the episode was basically me complaining about weird things the wistia library made me do, but that also may be helpful for you to see that you have to do them and not feel bad about doing them.

And in case you’re wondering what the feature was that I was working on there, it’s a version of this where if you change the speed in one of your videos, so I change it to 1.5 there, if you go to another video, it’ll stay that same speed. So enjoy this new feature, and I’ll see you next time.

Subscribe to our mailing list