Server Side Rendering failed: ERROR ReferenceError: window is not defined - msal.js

Any way to configure msal-angular to allow for server side rendering? I suspect this is due to a call with window which is not compatible with node on the server side. This error happens whenever I set the msalinterceptor. I am getting the following error when attempting to do this:
ERROR ReferenceError: window is not defined
at AuthCache.BrowserStorage

Unfortunately, MSAL Angular v1 does not support server-side rendering (i.e. Angular Universal). This will be supported in MSAL Angular v2, which we are working on now.

Related

Debug compilation errors errors using Angular Universal in Angular 8 Application

A Brief Backstory
I have been implementing several upgrades to an Angular 8 application such as server-side rendering, and Google Analytics. As most developers do, I would code then test then move on to the next task. Typically I use ng serve to run the application as I am developing.
With Server-side rendering, to test speed, lazy-loaded images, etc, you need to use a node express server running on a generated JS file. After building, etc, I use Node prerender (my js file is prerender.js) to see what the application will look like prerendering on the server.
When I run this command, I should not get any errors, and I know my prender file will start a local server on port 4000.
The Problem
I get errors when running a node express server that I do not get when running with ng serve I recently got an error that said:
Unhandled Promise rejection: Cannot read property 'subscribe' of undefined ; Zone: <root> ; Task: Promise.then ; Value: TypeError: Cannot read property 'subscribe' of undefined
at new ApplicationRef (C:\4towerdevelopment\dist-stage\server\main.js:45910:37)
at _createClass (C:\4towerdevelopment\dist-stage\server\main.js:37184:20)
at _createProviderInstance (C:\4towerdevelopment\dist-stage\server\main.js:37138:26)
at initNgModule (C:\4towerdevelopment\dist-stage\server\main.js:37044:32)
at new NgModuleRef_ (C:\4towerdevelopment\dist-stage\server\main.js:38176:9)
at Object.createNgModuleRef (C:\4towerdevelopment\dist-stage\server\main.js:38159:12)
at NgModuleFactory_.create (C:\4towerdevelopment\dist-stage\server\main.js:50821:25)
at C:\4towerdevelopment\dist-stage\prerender.js:29175:43
at ZoneDelegate.invoke (C:\4towerdevelopment\dist-stage\prerender.js:481:26)
at Object.onInvoke (C:\4towerdevelopment\dist-stage\prerender.js:28683:33) TypeError: Cannot read property 'subscribe' of undefined
at new ApplicationRef (C:\4towerdevelopment\dist-stage\server\main.js:45910:37)
at _createClass (C:\4towerdevelopment\dist-stage\server\main.js:37184:20)
at _createProviderInstance (C:\4towerdevelopment\dist-stage\server\main.js:37138:26)
at initNgModule (C:\4towerdevelopment\dist-stage\server\main.js:37044:32)
at new NgModuleRef_ (C:\4towerdevelopment\dist-stage\server\main.js:38176:9)
at Object.createNgModuleRef (C:\4towerdevelopment\dist-stage\server\main.js:38159:12)
at NgModuleFactory_.create (C:\4towerdevelopment\dist-stage\server\main.js:50821:25)
at C:\4towerdevelopment\dist-stage\prerender.js:29175:43
at ZoneDelegate.invoke (C:\4towerdevelopment\dist-stage\prerender.js:481:26)
at Object.onInvoke (C:\4towerdevelopment\dist-stage\prerender.js:28683:33)
The closest this gets me to figuring what actually is causing the problem is letting me know that a provider somewhere is causing this error. Looks like something should be an observable rather than a subscription. Beyond that, I guess I just start looking through my providers. My question is:
How can I force Angular to possibly throw this error when developing using ng serve?
If I can't, is there a better way to debug this current error besides combing through each provider? Or at least a way to tell what service is causing the issue?
Thank you.
UPDATE: Basic repo with problem here. I made a new angular project, made sure dependencies were up to date, installed ngUniversal per this post, and received this same Unhandled promise message when running node prerender
Verbatim I went to to the Angular cli website, made a new project (default Angular version installed was 8.3), installed Angular Universal, and tried to build. Same error message as above.
This looks like it was ApplicationRef that triggered the error, and that class is provided internally by the Angular core.
It could be failing in the constructor of the class, and there are a few calls to subscribe on Zone observables. I don't think you're going to find anything in your source code that directly relates to this error. It looks like a build configuration problem.
https://github.com/angular/angular/blob/bb52fb798c8578c461d21aee2b7623232184a5d3/packages/core/src/application_ref.ts#L562
I do not know what could possibly produce this problem, but I would start a new project with SSR and compare the differences to your current project.
Eventually, I dropped the angular 6 approach using pre-render, and went with the latest universal package. There seems to be no problem building using npm run build:ssr and serving dist/server.js in an express server. I am not sure what the problem was with the pre-render approach, but it seems to be outdated anyways. #Reactgular thanks for the feedback.

Is it possible to use dialogflow-nodejs-client-v2 in front-end (Angular)?

I built an app a long time ago using Firebase and dialogflow-javascript-client.
Now, dialogflow-javascript-client is deprecated. Since dialogflow-nodejs-client-v2 is a node.js client, it is not supposed to run on Angular. Did they drop the javascript support? I can't get any answer from the devs, they just seem to avoid it.
If it is not possible, my only solution is to drop support of Dialogflow in my app.
There is absolutely not documentation or info for users migrating from Javascript, here is the only thing they give you:
Off course I tried to run it anyway, thinking it was also built to run on javascript...
But here is what I get:
WARNING in
./node_modules/google-gax/node_modules/grpc/node_modules/node-pre-gyp/lib/util/versioning.js
17:20-67 Critical dependency: the request of a dependency is an
expression
WARNING in
./node_modules/google-gax/node_modules/grpc/node_modules/node-pre-gyp/lib/pre-binding.js
20:22-48 Critical dependency: the request of a dependency is an
expression
WARNING in
./node_modules/google-gax/node_modules/grpc/src/grpc_extension.js
32:12-33 Critical dependency: the request of a dependency is an
expression
WARNING in
./node_modules/google-gax/node_modules/grpc/node_modules/minimatch/minimatch.js
Module not found: Error: Can't resolve 'path' in
'D:\ng\ww-app\node_modules\google-gax\node_modules\grpc\node_modules\minimatch'
WARNING in ./node_modules/minimatch/minimatch.js Module not found:
Error: Can't resolve 'path' in 'D:\ng\ww-app\node_modules\minimatch'
ERROR in ./node_modules/dialogflow/src/v2/agents_client.js Module not
found: Error: Can't resolve './agents_client_config' in
'D:\ng\ww-app\node_modules\dialogflow\src\v2'
.... (many more following)
The dialogflow-nodejs-client-v2 only supports a node.js environment. To update your agent to V2, you should create a Cloud Function for Firebase that sends requests to dialogflow-nodejs-client-v2, then call that Cloud Function from your Angular code rather than calling the API directly.
There is a major benefit of this approach: you will no longer have your API credentials exposed on the client side, which is a security risk.
I read a tutorial once with Node.js, maybe you can migrate your data from angular to Node.js like in this question anwered before.
I found another solution:
I've created a javascript client... and I get token from nodejs api getToken endpoint when it expires (that is every hour)... I have restricted the getToken endpoint to the same domain.

tsconfig compilerOptions "module": "system" not working

In the angular2 5 min tutorial they use "system" as the module in the tsconfig. I have systemjs as a node_module but when trying to start my server I get System is not defined, from the first line of the compile js-file which looks like this:
System.register(['http', 'express', './config/index', 'path'], function(exports_1) {
Why is System undefined even though I have it as a node dependency?
I was trying to change it to commonjs, then the compiled js looks much simpler. But then I get errors in the angular application.
What am I missing in order for it to work with SystemJs?
Edit
I think I was bad at explaining my problem. When changing from importing modules into my server.ts file "javascript style" (var http = require('http');) to I guess "typescript style" (import * as http from 'http';) I start getting the error specified above. When doing it javascript style the compiled js looks just the same as the ts (var http = require('http');) however when doing it "typescript style" it gets compiled with modules being imported using System (the line of code specified above). So i'm getting this error when trying to start the node server and not in the browser.
I tried changing the compilerOption "module" to "commonjs" instead of "system" in tsconfig.json, doing that causes errors in the browser (this error, only the solutions doesn't seem to fit) for some weird reason so i figured i'd try with "system". But then I ran into the problem of not have System defined. So how do I get access to System when starting the node server?
It looks like you are missing reference to system.js in your index.html. Angular is meant to be run by browsers so its not enough to have it as node dependency, browser will not load it automatically. And of course do not try to run angular application on server side in node.js. What you want to do on server-side (node.js) is to run some web server that will serve content to the browser (http-server, lite-server, etc). And then open your index.html served by web server in browser that in turn will run angular2 application using system.js for module loading.
If you do have system.js referenced in index.html and you are not trying to run it on node.js server side - make sure the path is correct and it does get loaded - by using development tools of any modern browser.

nwjs reactjs, confused about my context. Document is undefined

In my nwjs application i am using React to build my UI. Currently, React is being loaded via a <script> tag in the main file, index.html. index.html has another <script> tag which loads main.js containing code which defines and renders my React components as well as requiring (require()) a few Node modules such as "fs" and "McFly".
This all seems to be working, however when i try using another node module (react-inlinesvg) i get an error, "document is undefined".
Having looked online for help, i have come to the conclusion that React now believes that it is being run on the server? Which is odd, as before i started using the react-inlinesvg module it was happily rendering components using React.render (clientside rendering).
If you need any more context or information then please ask.
It could be that you are rendering on the server side, or also that you are rendering both sides. In the second case you could simple nest the line that is causing you error with:
if (process.env.BROWSER) {
the line causing the error
}
If the error disappears, it means that you are on the server side also!
I hope this helps...
Basically if you code is universal (or isomorphic, if you want...) with this check you can execute the code only on client side, you want to do this to use a particular style-sheet for example:
if (process.env.BROWSER) {
require("../style/main.scss");
}
Naturally if you want to do stuff server-side you can check
if (!process.env.BROWSER) {
}
if any one face this he can solve it in 2 ways:
Solution 1: if you are using nw.js 15 or above try to enable mix context mode:
in your package.json add this flag:
"chromium-args": "--mixed-context"
Solution 2: expose document to the global object using this hack:
global.document = window.document;

How to debug a '4005 Path Not Found' error?

I am trying to integrate Pusher with my web application that uses backbone.js. I'm following the Pusher with Backbone guide in the Pusher docs.
So I'm seeing this error pop up in the web console on application start up
Pusher : Error : {"type":"PusherError","data":{"code":4005,"message":"Path not found"}}
What is this 'path' that cannot be found? I found nothing in the Pusher docs.
A 4005 error generally means that the WebSocket URL you are using doesn't identify an application to connect to.
In terms of usage of the Pusher JavaScript library this means you've likely supplied an empty string as the app_key to the Pusher constructor.
var pusher = new Pusher('');
You can see this in action here:
http://jsbin.com/evulaj/1/edit
Open the JavaScript console to see the error. You can also check the app_key value set by checking pusher.key.
Note: I appreciate this error is a bit cryptic. I'll see if we can remedy this
in my case, wsHost: process.env.MIX_PUSHER_WS_HOST was giving an empty value, and fixed it by changing .env file.
PUSHER_WS_HOST=my.host.com
MIX_PUSHER_WS_HOST="${PUSHER_WS_HOST}"
or you can do:
wsHost: window.location.hostname

Resources