(Angular 6) Angular Universal - Not waiting on content API call

馋奶兔 提交于 2019-11-27 23:45:26

问题


Cannot get SSR to work when using Angular Universal with pages that use dynamic content. All other pages work and the dynamic pages return with HTML but do not include the dynamic data.

Method Called:

ngOnInit() {
  const div = this.renderer.createElement('div');
  const texttest = this.renderer.createText('this works');

  this.renderer.appendChild(div, texttest);
  this.renderer.appendChild(this.content.nativeElement, div);

  this.createLinkForCanonicalURL();

  // The HTML never shows, the method works fine.
  this._contentfulService.getBlogPosts().then(posts => {
    this.blogPosts = _.orderBy(posts, ['sys.createdAt'], ['desc']);
  });
}

Service Method

getBlogPosts(query ? : object): Promise<Entry<any>[]> {
  return this.cdaClient.getEntries(Object.assign({
      content_type: CONFIG.contentTypeIds.blogPosts
    }, {
      'fields.private': false
    }))
    .then(res => res.items);
}

Template:

This never shows in the source.

<li class="blog-post" *ngFor="let post of blogPosts">
  <h1>{{post.fields.title}}</h1>
</li>

Have tried the starter kits and they do not work calling the same method. Also tried render2 to inject and a resolver service to test fetching data before the load.

Nothing seems to work?

Any help would be appreciated!

EDIT

This is my server.ts file

// These are important and needed before anything else
import 'zone.js/dist/zone-node';
import 'reflect-metadata';

import { enableProdMode } from '@angular/core';
import * as express from 'express';
import { join } from 'path';

// Faster server renders w/ Prod mode (dev mode never needed)
enableProdMode();

// Express server
const app = express();

const PORT = process.env.PORT || 8080;
const DIST_FOLDER = join(process.cwd(), 'dist');

// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = 
require('./dist/server/main');

// Express Engine
import { ngExpressEngine } from '@nguniversal/express-engine';
// Import module map for lazy loading
import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader';

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

app.set('view engine', 'html');
app.set('views', join(DIST_FOLDER, 'browser'));

// TODO: implement data requests securely
app.get('/api/*', (req, res) => {
  res.status(404).send('data requests are not supported');
});

// Server static files from /browser
app.get('*.*', express.static(join(DIST_FOLDER, 'browser')));

// All regular routes use the Universal engine
app.get('*', (req, res) => {
  res.render('index', { req });
});

// Start up the Node server
app.listen(PORT, () => {
  console.log(`Node server listening on http://localhost:${PORT}`);
});

and my app server module

@NgModule({
bootstrap: [AppComponent],

imports: [
    BrowserModule.withServerTransition({ appId: 'app-root' }),

    AppModule,
    ModuleMapLoaderModule,
    ServerModule,
    NoopAnimationsModule,
    ServerTransferStateModule, // comment
]
})
export class AppServerModule { }

回答1:


You need use TransferHttpCacheModule for wait HTTP call to API or use another implementation that work with TransferState like ngx-transfer-http .

My sample with wait 3-second delay: https://github.com/Angular-RU/angular-universal-starter/blob/master/src/app/transfer-back/transfer-back.component.ts




回答2:


Try to edit your code as follows:

async ngOnInit() {
  const div = this.renderer.createElement('div');
  const texttest = this.renderer.createText('this works');

  this.renderer.appendChild(div, texttest);
  this.renderer.appendChild(this.content.nativeElement, div);

  this.createLinkForCanonicalURL();

  const posts = await this._contentfulService.getBlogPosts();
  this.blogPosts = _.orderBy(posts, ['sys.createdAt'], ['desc'])

 }



回答3:


It seems that angular universal doesn't wait for async calls to render.

I had the same problem and finally made it work using ZoneMacroTaskWrapper as mentioned in this issue.

This is the service I made.



来源:https://stackoverflow.com/questions/52270397/angular-6-angular-universal-not-waiting-on-content-api-call

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!