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

Angular Universal and openlayers #108

Open
Phreeman703 opened this issue Oct 14, 2017 · 8 comments
Open

Angular Universal and openlayers #108

Phreeman703 opened this issue Oct 14, 2017 · 8 comments

Comments

@Phreeman703
Copy link

Phreeman703 commented Oct 14, 2017

I have a Angular 4 Universal app and i use openlayers. If i run app with client-side app work, but if i try run app with server side render, i caught an exception "window is not define".

@quentin-ol
Copy link
Collaborator

I'm sure to fully understand what you're trying to achieve. Could you be more specific?
What do you mean by server-side rendering. AFAIK Openlayers is a client side library, i.e. meant to run in a browser, electron, etc.

@Phreeman703
Copy link
Author

I mean Angular Universal/. If I run app through angular-cli (ng serve), app is build and run. But if i trying to run Angular Universal show exception "window is not define", because openlayers use window(or document) for rendering map, but Angular Universal doesn't allow use widow(or document)

@quentin-ol
Copy link
Collaborator

Thanks for the information. I suggest you submit an issue in the Openlayers repo then (since the exception occurs in their code). Regarding this, I'm also in favour of letting the developer provide a replacement image in such case, i.e. if the map cannot be instantiated, provide a static image in place of the map. This could be done that way:

<aol-map [alt-img]="path_to_img">
</aol-map>

That should allow for server side rendering.
Opinions?

@Phreeman703
Copy link
Author

I'm trying to insert a static picture, but I throw an error:

ERROR in Template parse errors:
Can't bind to 'alt-img' since it isn't a known property of 'aol-map'.

@quentin-ol
Copy link
Collaborator

Hey @Phreeman703, the above code was a mock-up, a proposal on the way to let user achieve this.
The underlying implementation is not done yet. But that's definitely in the todo-list.

@Phreeman703
Copy link
Author

Phreeman703 commented Nov 20, 2017

oh... @quentin-ol, i wasn't understood that is mock-up(( I found the solution with window. In server.ts need mock-up global['window'] = win and use domino

const domino = require('domino'),
      fs = require('fs'),
      path = require('path'),
      template = fs.readFileSync(path.join(__dirname, '.', 'dist', 'index.html')).toString(),
      win = domino.createWindow(template);

global['window'] = win;
global['document'] = win.document;

import 'reflect-metadata';
import 'zone.js/dist/zone-node';
import { platformServer, renderModuleFactory } from '@angular/platform-server';
import { enableProdMode } from '@angular/core';
import * as express from 'express';
import * as compression from 'compression';
import * as cookieparser from 'cookie-parser';
const { provideModuleMap } = require('@nguniversal/module-map-ngfactory-loader');

/*const fs = require('fs');
const path = require('path');*/

const files = fs.readdirSync(`${process.cwd()}/dist-server`);
const mainFiles = files.filter(file => file.startsWith('main'));
const hash = mainFiles[0].split('.')[1];
const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require(`./dist-server/main.${hash}.bundle`);
import { ngExpressEngine } from '@nguniversal/express-engine';
import { REQUEST, RESPONSE } from '@nguniversal/express-engine/tokens';
const PORT = 4000;

enableProdMode();

const app = express();
app.use(compression());
app.use(cookieparser());

// const template = fs.readFileSync(path.join(__dirname, '.', 'dist', 'index.html')).toString();

app.engine('html', ngExpressEngine({
  bootstrap: AppServerModuleNgFactory,
  providers: [
    provideModuleMap(LAZY_MODULE_MAP)
  ]
}));

app.set('view engine', 'html');
app.set('views', 'src');

app.get('*.*', express.static(path.join(__dirname, '.', 'dist')));

app.get('*', (req, res) => {
  /*global['window'] = global;
  global['document'] = template;*/
  global['navigator'] = req['headers']['user-agent'];
  /*global['CSS'] = null;*/

  res.render('../dist/index', {
    req: req,
    res: res,
    providers: [
      {
        provide: REQUEST, useValue: (req)
      },
      {
        provide: RESPONSE, useValue: (res)
      }
    ]
  });
});

app.listen(PORT, () => {
  console.log(`listening on http://localhost:${PORT}!`);
}); 

but the solution led to another error. Can not use 'in' operator to search for 'geolocation' in undefined. Soree all this happens, because they made a mock-up 'window'

@AbdallahAbdedaiem
Copy link

Please let me know if you found a solution for this.

@jeandonaldroselin
Copy link

@AbdallahAbdedaiem there is a solution there submitted by a developer => #202.

But the Pull Request is still not merged after two years @quentin-ol are you alive ? lol.

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

No branches or pull requests

4 participants