1

I have an angular2 (with angular-cli) app that will exist inside a web page of a website that is provided by a CMS (DotnetNuke). This web cms uses the services framework of jquery to generate a validation token for api calls to the website's "backend". As a result I can not generate any web api calls to the website until I have this validation token.

I created a service to handle the calls to the website's api(s). In the constructor of the service I try to set the token in the following way (the ServicesFramework Object has a function called getAntiForgeryValue which returns the token ):

@Injectable()
export class ApiService {

    private http: Http;

    constructor(http: Http) 
    {
        console.log('dnn service constructor');

        $(document).ready(function () {
            this._dnnSF = $.ServicesFramework(804);
        });
    }

    getRequestVerificationToken(): any {
        return this._dnnSF.getAntiForgeryValue();        
    };
}

The getAntiForgeryValue() of the ServicesFramework just returns the jQuery __RequestVerificationToken for ajax calls to .net web api endpoints. This is just for explanation.

The Issue:

The other components that get this service injected are calling the getAntiForgeryValue() before the document.ready is complete in the services's constructor and therefore I am getting:

Cannot read property 'getAntiForgeryValue' of undefined

Question: Can someone help me work out a strategy with angular2 where I can wait for this validation token to be provided before the angular app runs or how to wait in the service for the constructor to complete.

Thanks in advance

J King
  • 4,108
  • 10
  • 53
  • 103

1 Answers1

1

That error means that: $.ServicesFramework is not defined. You need to find a way to inject it into the Angular world. One way (not recommended but quick) is to declare it in the global scope outside of Angular: window.framework = $.ServicesFramework;

Then declare it on the top of your service: const framework;

Then in your constructor you can do this: constructor(http: Http) { this._dnnSF = framework; }

List I said this is quick and dirty. The better way would be to inject the external component when you bootstrap your Angular application.

Ben Richards
  • 3,437
  • 1
  • 14
  • 18
  • thanks Boyan, I was previously using opaque tokens and injecting the $.ServicesFramework in the providers of the root ngModule. But the provider was complaining that the value of $.ServicesFramework was undefined. It seemed to not want to provide/inject an object that was yet undefined. That is why I tried to change my approach. I will give yours a try. – J King Oct 29 '16 at 16:22
  • Your initial approach was the better one. If you want to inject the module on bootstrap, but it's not available right way, you need to do it by using a promise that waits for the external component to be loading, and in the promise callback, bootstrap your application and inject the ready object. More on this from another answer. http://stackoverflow.com/questions/37611549/how-to-pass-parameters-rendered-from-backend-to-angular2-bootstrap-method – Ben Richards Oct 30 '16 at 05:18