Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(universal): should play nice with angular/universal #61

Closed
akorchev opened this issue Jan 5, 2016 · 17 comments
Closed

chore(universal): should play nice with angular/universal #61

akorchev opened this issue Jan 5, 2016 · 17 comments

Comments

@akorchev
Copy link

akorchev commented Jan 5, 2016

Currently ng2-bootstrap uses MouseEvent, KeyboardEvent and window which prevents it from using in universal angular2 application because those aren't defined server-side.

@valorkin
Copy link
Member

valorkin commented Jan 5, 2016

I knew about this problem, server side rendering + mobile ready + aria is key features
I can agree about window usage is bad, but universal should support MouseEvent and KeyboardEvent
or not? @jeffwhelpley @gdi2290

@valorkin valorkin changed the title Can't easily use with angular/universal chore(universal): should play nice with angular/universal Jan 5, 2016
@akorchev
Copy link
Author

akorchev commented Jan 5, 2016

Right now the problem with MouseEvent and KeyboardEvent is the generated JavaScript code:

__metadata('design:paramtypes', [MouseEvent])

When you require such code in node it will fail because MouseEvent isn't defined.

@valorkin
Copy link
Member

valorkin commented Jan 5, 2016

Can you generate code without meta?

@jeffwhelpley
Copy link

The deal is that we can add monkey patch functionality for window on the server for anything but we purposely didn't add any to start with because in most cases you should try to use the Angular API and if a use case comes up that requires direct access to the DOM objects then we need to decide if it is truly something everyone should need or if you should just add it yourself for your project.

In this case, it isn't a question of whether to implement the keyboard and mouse event functionality. Rather, whether we should have empty global objects so that the code doesn't fail. Can you link the ng2-bootstrap code that references KeyboardEvent and MouseEvent? Maybe we can think of alternative solutions.

@jeffwhelpley
Copy link

Ah, OK, now I get it. So, @gdi2290 let me know what you think, but my solution for this would be to simply include an interfaces file. No need to even provide an implementation because it is just a typing issue. Perhaps someone has already done this?

@PatrickJS
Copy link

the angular repo uses 'angular2/src/facade/browser'

var win = window;

export {win as window};
export var document = window.document;
export var location = window.location;
export var gc = window['gc'] ? () => window['gc']() : () => null;
export var performance = window['performance'] ? window['performance'] : null;
export const Event = window['Event'];
export const MouseEvent = window['MouseEvent'];
export const KeyboardEvent = window['KeyboardEvent'];
export const EventTarget = window['EventTarget'];
export const History = window['History'];
export const Location = window['Location'];
export const EventListener = window['EventListener'];

which has a problem with global that is solved via 'angular2/src/facade/lang'

declare var WorkerGlobalScope;
var globalScope: BrowserNodeGlobal;
if (typeof window === 'undefined') {
  if (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) {
    // TODO: Replace any with WorkerGlobalScope from lib.webworker.d.ts #3492
    globalScope = <any>self;
  } else {
    globalScope = <any>global;
  }
} else {
  globalScope = <any>window;
};

If they're types, then it should be okay since they are removed in es5. If you're creating these types, then you should use the DomAdapter.

@valorkin
Copy link
Member

valorkin commented Jan 5, 2016

@gdi2290 thanks a lot, I will fix it

@devCrossNet
Copy link

Hey, I have a problem with angular2-universal and the collapse component.

I know it is because of the use of this._el.nativeElement.

I read in the Universal documentation that we should use the Renderer instead of the nativeElement. But the Renderer has no getters (for styles).

I tried to use the DomAdapter, here is my code:
let scrollHeight = DOM.getStyle(this._el.nativeElement, 'scrollHeight');

But it throws an error in the express API:
Parse5DomAdapter.prototype.getComputedStyle = function (el) { throw 'not implemented'; };

My quick fix is, that I have a condition in the toggle function:

if (!this._el.nativeElement.style) { return; }

Any thoughts on that?

@devCrossNet
Copy link

I made an alternative implementation for the collapse component, it works with universal and is more like the original bootstrap component: https://gist.github.com/devCrossNet/0b57b60f0199423d37261880a6edca55

I use try-catch with the DOM functions now, to get no errors on the server-side.

@PatrickJS
Copy link

I have some time to work on this now if @valorkin has some time to pair online for an hour or two

@valorkin
Copy link
Member

valorkin commented Apr 2, 2016

For you @gd2i290 I will find a time :)

@tdonohue
Copy link

tdonohue commented Apr 8, 2016

Any updates on the progress of this issue? We're watching this closely as we'd like to be able to use ng2-bootsrap with Angular Universal. Currently, attempting to even just use BUTTON_DIRECTIVES from ng2-bootstrap results in errors like these from the server-side compilation process.

var w = window;
ReferenceError: window is not defined

We use a build process similar to that in https://github.com/angular/universal-starter

@vincentwinkel
Copy link

vincentwinkel commented Apr 22, 2016

Hi,
I've same problem using Universal starter + ng2-bootstrap.
It could be nice to have an interface or something else to wrap 'window' calls.
In my case, the code in 'angular2/src/facade/browser' visible above is wrong because of 'window' calls instead of 'win' ones.

@PatrickJS
Copy link

for universal don't use angular2/src/facade/browser

@valorkin
Copy link
Member

working hack

import {global} from 'angular2/src/facade/lang';
/* tslint:disable */
const KeyboardEvent = (global as any).KeyboardEvent as KeyboardEvent;
/* tslint:enable */

@valorkin
Copy link
Member

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants