Angular Checks for Universal and Browsers

When developing a web application with jQuery or plain JavaScript, it is usually necessary to check for features. For example, if I want to use the document.oncopy event, I must first have something like this to ensure that my code does not interrupt for smaller browsers:

 if ("oncopy" in document) { // Feature is available } 

I am a little puzzled by how this works in Angular2. I could still use the same if I expected you to run only in the browser, but I was just told to leave only the DOM if I want to use Angular Universal and instead depend on templates or DomRenderer. This allows you to pre-display the page on the server and provides a truly impressive increase in performance.

But suppose I want a particular div to be invisible if document.oncopy not available. I understand that this is not recommended:

 <div *ngIf="hasFeature()">...</div> 

and

 hasFeature() { return 'oncopy' in document; } 

because then I'm still manipulating the DOM. Please note that my example refers to document.oncopy , but I could choose any function that does not have universal support.

I tested this using Chris Nwamba 's Scotch tutorial and added the following to the end of my home template:

 <div *ngIf="hasFeature()">Feature is supported</div> <div *ngIf="!hasFeature()">Feature is NOT supported</div> 

Update: Interestingly, it gave different results in different browsers. On Chrome 55, it ran as usual and showed the message โ€œFeature Supportedโ€. In IE11, I received a "not supported" message. In both cases, the server log shows the message EXCEPTION: document is not defined , but the page still looks fine.

So, what is the correct way to test browser functions if I want to use Angular Universal?

Update: I also played using the field in the template and assigned this field from one of

+5
source share
1 answer

There are two ways to approach this:

  • Perform the check only after the server has completed the rendering and the client is fully initialized (including repeating user events executed using preboot.js ).
  • Returns to a reasonable default when the page runs on the server and the actual check is performed only in the browser.

I started looking at the first option, but none of the Angular2 life cycle events will help. In fact, you can clearly see how they all run on the server and only then on the client.

Then I started looking for something useful in preboot.js , but quickly realized that it was more complicated than necessary.

So, I went to option 2. It turns out that checking for a browser is as simple as importing and checking isBrowser .

 import { isBrowser } from "angular2-universal"; @Component({ // All the usual stuff }) export class MyComponent { // ... hasFeature(): boolean { return isBrowser && 'oncopy' in document; } // ... } 

And then use the template as I showed in the question.

To check if it is running on the server, import and use isNode in the same way. There seems to be no obvious way to distinguish between Node and ASP.NET Core, but it might be better not to write too much platform-specific code.

0
source

Source: https://habr.com/ru/post/1262222/


All Articles