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

Angular2 Universal support #6

Closed
u12206050 opened this issue Oct 12, 2016 · 13 comments
Closed

Angular2 Universal support #6

u12206050 opened this issue Oct 12, 2016 · 13 comments

Comments

@u12206050
Copy link
Contributor

Am getting this error when trying to run ng2-buttons with Angular2's Universal (prerender) on the server side:

EXCEPTION: window is not defined
ORIGINAL STACKTRACE:
ReferenceError: window is not defined
    at e.ngAfterViewInit (/var/www/drupal/frontend/universal-starter/node_modules/ng2-sharebuttons/dist/components/share-button/share-button.component.js:1:983)

It works without prerender. This is a common error it seems in components that try to use window.

@MurhafSousli
Copy link
Owner

@u12206050 Yup, it uses window.open() to open the dialog, let me investigate this further for you

@u12206050
Copy link
Contributor Author

u12206050 commented Oct 12, 2016

The main problem is the use of window.location.href, I believe angular does have a Location object that you can use. Luckily window.open() doesn't get called when rendering on the server so that isn't such a big deal.

For others wanting to fix this, I did the following to fix the window.location.href:

Replaced window.location.href with
typeof window != 'undefined' ? window.location.href : typeof global != 'undefined' ? global.url : ''

And then in server.ts where Universal is being called to render do the following:

/* Declare both global and the url property for typescript concerns */
interface Global {
  url: string;
}
declare var global: Global;

/* In the function that responds with the rendered html */
let ngApp = (req, res) => {
  let url = req.originalUrl || '/';
  global.url = url;

  ...
}

@MurhafSousli
Copy link
Owner

MurhafSousli commented Oct 12, 2016

@u12206050 I got it, it turned out that there's no window in node, @ViewChild('firstModal') could be a solution

@u12206050
Copy link
Contributor Author

Is this fixed now?

@MurhafSousli
Copy link
Owner

MurhafSousli commented Oct 26, 2016

@u12206050 I haven't played with Universal yet, but now sharebuttons will only use window.location.href if the [url] input is not provided, so pass your current url to the input and it should work

@MurhafSousli
Copy link
Owner

MurhafSousli commented Oct 26, 2016

@u12206050 For opening share window which uses window.open I'm not sure if it can be fixed in Universal, I talked about it in angular group
capture
I would have used a modal instead of window,open, but fb have SAMEORIGIN policy, which disallows sharing within iframe outside of their domain..

@u12206050
Copy link
Contributor Author

Could you just please do the following, it fixes compiling on universal side at least.
Replaced window.location.href with
typeof window != 'undefined' ? window.location.href : typeof global != 'undefined' ? global.url : ''

@MurhafSousli
Copy link
Owner

MurhafSousli commented Nov 4, 2016

@u12206050 okay it's merged now, please download the source manually and test it in your app, if it works I will push it to npm, because I'm not sure if it would work with window.open. isn't it a problem for universal to compile?

btw, I tried to replace window.location.href with router.url, location.path() and location.prepareExternalUrl(location.path()), they all don't return the full path, also couldn't find any alternative to window.open. we can't get rid of it

@u12206050
Copy link
Contributor Author

Ok, the changes should work, except that window and global are undefined in the context of typescript when compiling. I made a merge request with the interfaces for them.

@MurhafSousli
Copy link
Owner

MurhafSousli commented Nov 14, 2016

I tried to use it on a fresh Universal Starter installation, I imported ShareButtonsModule in both app.browser.module and app.node.module, it worked.
The only issue I found is when I click on Pinterest button. Cannot read property 'getAttribute' of null, but everything else is working as expected!
BTW this is without the changes we made earlier 👆
capture

@MurhafSousli
Copy link
Owner

Changes are merged and pushed to npm in 1.0.7

@u12206050
Copy link
Contributor Author

Did you make use of the share buttons on universal side or do you only render them client side?

@MurhafSousli
Copy link
Owner

MurhafSousli commented Nov 16, 2016

Did you make use of the share buttons on universal side

@u12206050 I just used it the same way I would use it in a normal angular app and it worked, I'm not sure what you mean by make use of them on universal side because I'm not technically familiar with universal yet. I have been told that global variables like window are not available in node apps, and we can't get rid of window completely since there is no other way to open the sharing dialog in a new window (not new tab).

u12206050 pushed a commit to u12206050/ng2-sharebuttons that referenced this issue Jan 9, 2017
This is related to the same issue MurhafSousli#6 where if you just try use window which is undeclared on Node then Angular Universal crashes.
A simple check makes sure window is not undefined, before using it.
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

2 participants