Search code examples
typescripttoastraurelia

How can toastr.js work in Aurelia and Typescript?


I can't seem to get these to work together. I'm using the Aurelia CLI and have done so in a similar manner for other libraries successfully(like select2, spin, moment and numeral). I can't seem to get toastr to work though. Here is what I have so far.

First I ran npm install toastr --save and typings install dt~toastr --global --save

In aurelia.json, in the vendor-bundle.js section, I added a dependency as such:

  "jquery",
  {
    "name": "toastr",
    "path": "../node_modules/toastr/build",
    "main": "toastr.min",
    "resources": [
      "toastr.min.css"
    ],
    "deps": ["jquery"]
  }

UPDATE: Full steps to repro

I have these versions of these tools installed: node (6.3.0), npm (3.10.3), au (0.17.0)

Open a command prompt and type:

au new au-toastr
3 (Custom)
2 (Typescript)
3 (Sass)
1 (configure unit testing)
1 (Visual Studio Code)
1 (create project)
1 (install project dependencies)
cd au-toastr
npm install jquery --save
npm install toastr --save
typings install dt~jquery --global --save
typings install dt~toastr --global --save

Then open aurelia.json in an editor and add

"jquery",
{
"name": "toastr",
"path": "../node_modules/toastr/build",
"main": "toastr.min",
"resources": [
"toastr.min.css"
],
"deps": ["jquery"]
}

to the bottom of dependencies.

Comment out line 1839(declare var $: cssSelectorHelper;) on typings/globals/angular-protractor/index.d.ts due to conflict with jquery's .d.ts file.

Replace app.ts contents with

import * as toastr from 'toastr';

export class App {
  activate() {
    toastr.info('blah');
  }
}

OR

import 'toastr';

export class App {
  activate() {
    toastr.info('blah');
  }
}

Type au run in the command prompt and then open a browser and navigate to the url that the command line says the application is available at(usually http://localhost:9000).


Attempt 1

import 'toastr';

export class ViewModel {
  activate() {
    toastr.info('blah');
  }
}

Error: ReferenceError: toastr is not defined


Attempt 2

import {autoinject} from 'aurelia-framework';
import 'toastr';

@autoinject()
export class ViewModel {
  constructor(private toastr: Toastr) {
  }

  activate() {
    this.toastr.info('blah');
  }
}

Error: TypeError: this.toastr.info is not a function


Attempt 3

import * as toastr from 'toastr';

export class ViewModel {
  activate() {
    toastr.info('blah');
  }
}

Error: TypeError: toastr.info is not a function


Attempt 4

import {autoinject} from 'aurelia-framework';
import * as toastr from 'toastr';

@autoinject()
export class ViewModel {
  constructor(private toastr: Toastr) {
  }

  activate() {
    this.toastr.info('blah');
  }
}

Error: TypeError: this.toastr.info is not a function


All of the above transpile properly when I run au build from the command line. I get no errors.

I'm lost as to what I am missing or what else I can try. Any help would be greatly appreciated!


UPDATE: My guess is that there is either a bug in the aurelia-cli or more likely I'm handling the package incorrectly somehow in regard to the aurelia-cli loading mechanism. When I get the typescript skeleton from their site, which is using jspm as it's module loader, and follow the same steps above, the toastr works just fine.

Any ideas how I can get this to work with the aurelia-cli?



Solution

  • After a lot of time and help from a friend, I was finally able to get this to work.

    Only a few changes should be necessary -

    aurelia.json needed to be updated to not use the minified version of the toastr library.

    {
      //...
      "dependencies": [
      //...
        "jquery",
        {
          "name": "toastr",
          "path": "../node_modules/toastr",
          "main": "toastr",
          "resources": [
            "build/toastr.min.css"
          ],
          "deps": ["jquery"]
        }
      ]
    }
    

    The toastr.info('here'); function invocation usually needs to happen in the attached method or after the element is available in the DOM.

    To require the HTML in app.html needs to be updated to

    <require from="toastr/build/toastr.min.css"></require>
    

    Hope this helps.


    UPDATE Then to use it in your view model, you could do it one of a few ways:

    import * as toastr from 'toastr';
    
    export class App {
      attached() {
        toastr.success('here');
      }
    }
    

    import { success } from 'toastr';
    
    export class App {
      attached() {
        success('here');
      }
    }