javascriptangulartypescriptangular-promisealertify

Angular 2: Promise rejection: alertify is not defined


I'm trying to make this (https://chsakell.com/2016/01/01/cross-platform-single-page-applications-with-asp-net-5-angular-2-typescript/) tutorial/example Single Page Application run on my machine (Visual Studio 2015, Win 7 Prof, Chrome Browser) and get the following runtime error in my browser console when trying to open the Albums page:

platform-browser.umd.js:937 Error: Uncaught (in promise): ReferenceError: alertify is not defined
at resolvePromise (zone.js:558)
at zone.js:535
at ZoneDelegate.invoke (zone.js:332)
at Object.onInvoke (core.umd.js:9245)
at ZoneDelegate.invoke (zone.js:331)
at Zone.run (zone.js:225)
at zone.js:591
at ZoneDelegate.invokeTask (zone.js:365)
at Object.onInvokeTask (core.umd.js:9236)
at ZoneDelegate.invokeTask (zone.js:364)BrowserDomAdapter.logError @ platform-browser.umd.js:937ExceptionHandler.call @ core.umd.js:4392next @ core.umd.js:9971schedulerFn @ core.umd.js:9168SafeSubscriber.__tryOrUnsub @ Subscriber.ts:240SafeSubscriber.next @ Subscriber.ts:192Subscriber._next @ Subscriber.ts:133Subscriber.next @ Subscriber.ts:93Subject._finalNext @ Subject.ts:154Subject._next @ Subject.ts:144Subject.next @ Subject.ts:90EventEmitter.emit @ core.umd.js:9156onError @ core.umd.js:9394onHandleError @ core.umd.js:9266ZoneDelegate.handleError @ zone.js:336Zone.runGuarded @ zone.js:242_loop_1 @ zone.js:508drainMicroTaskQueue @ zone.js:515ZoneTask.invoke @ zone.js:437

zone.js:484 Unhandled Promise rejection: alertify is not defined ; Zone: angular ; Task: Promise.then ; Value: ReferenceError: alertify is not defined(…) ReferenceError: alertify is not defined
    at new NotificationService (http://localhost:9823/lib/spa/core/services/notificationService.js:14:26)
    at AppView._View_Albums_Host0.createInternal (Albums.ngfactory.js:15:35)
    at AppView.create (http://localhost:9823/node_modules/@angular/core//bundles/core.umd.js:12439:25)
    at ComponentFactory.create (http://localhost:9823/node_modules/@angular/core//bundles/core.umd.js:9047:40)
    at ViewContainerRef_.createComponent (http://localhost:9823/node_modules/@angular/core//bundles/core.umd.js:8354:49)
    at eval (http://localhost:9823/node_modules/@angular/core//bundles/core.umd.js:10295:33)
    at ZoneDelegate.invoke (http://localhost:9823/node_modules/zone.js/dist/zone.js:332:29)
    at Object.onInvoke (http://localhost:9823/node_modules/@angular/core//bundles/core.umd.js:9245:45)
    at ZoneDelegate.invoke (http://localhost:9823/node_modules/zone.js/dist/zone.js:331:35)
    at Zone.run (http://localhost:9823/node_modules/zone.js/dist/zone.js:225:44)

The notificationService.ts in question. Notice this declares alertify outside of the class to avoid compile time notifications:

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

declare var alertify: any;

@Injectable()
export class NotificationService {
    private _notifier: any = alertify;

    // irrelevant other code
}

Generated notificationService.js. seems to have nothing corresponding to "declare var alertify: any;". Might be OK because alertify is an external JavaScript library, but still peculiar:

"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var core_1 = require('@angular/core');
var NotificationService = (function () {
    function NotificationService() {
        this._notifier = alertify;

    // irrelevant other code
}());

I'm using the latest code of the project from github: https://github.com/chsakell/aspnet5-angular2-typescript

I had to change the .NET Core version from 1.0.0-preview1-002702 to 1.0.0-preview2-003121 in global.json.

All installation instructions for Visual Studio 2015 in the github readme were followed.

I ran the following additionally in Package Manager Console:' bower install alertify.js

One thing that looks strange is that the versions between alertify.js under Bower (0.3.11) and the same under NPM (1.0.12) are mismatched. I tried changing the alertify version to 1.0.12 in Bower.json and install alertify again, but this fails:

bower alertify.js#1.0.12  ENORESTARGET No tag found that was able to satisfy 1.0.12

changing the version in package.json for NPM also fails when running cmd "npm install":

ERR!
 version not found: alertify.js@0.3.11

What could be wrong? I'm very new to all of this material so any explanation as to what is going on would be helpful.

update: adding the .js and .css files downloaded from http://alertifyjs.com/ to the wwwroot/lib folder and updating the stylesheet references in index.cshtml stops the error from appearing and makes the notification boxes show up beautifully. I feel like this is still a suboptimal solution since this approach requires me to update the alertify files manually instead of making use of bower and NPM's full potential. If you have suggestions on how to improve on this solution, let me know.


Solution

  • I've seen that tutorial too, the problem for me was that alertify is discontinued, and therefore even though bower recognizes it, the .js files don't get downloaded. You should google alertify.js, download the scripts manually and place them into the folder your app would look for them. This solved the problem for me.

    Also, until you get familiar of how all the things work togeter (and especially until the tooling in VS improves) I suggest using VS Code instead. Getting that tutorial up and running was way easier using that.