如何使Angular Universal等待API响应?我使用了transferState,在路线上解析等

时间:2019-09-03 21:35:32

标签: angular universal

我试图让Angular等待API响应,但是没有成功。

我使用了TransferState,它可以工作,但是结果没有出现在“视图源”中。加载视图后,角度仍会闪烁以显示响应。

我在route模块上使用了resolve参数,但这是同一件事。

我正在使用Universal Starter https://github.com/angular/universal-starter

我使用了reqres.in和https://jsonplaceholder.typicode.com/之类的测试API,它们可以工作。两者都显示在视图源中,但是使用Laravel 5创建的API却没有,我也不知道为什么。我的API以毫秒为单位的响应速度甚至比jsonplaceholder快,但我对响应所做的ngFor(数组)仍然没有显示在“查看源代码”中。

我的服务上有这个。

import { environment } from './../../../environments/environment';
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class NestedService {

  // ----------  Headers -----------------
  public headers: HttpHeaders = new HttpHeaders({
    Accept: 'application/json',
    'Content-Type': 'application/json'
  });

  constructor(
    private http: HttpClient
  ) { }

  public getReq() {
    return this.http.get(environment.REQRES);
  }

  public mostrarProductos() {
    return this.http.get('https://jsonplaceholder.typicode.com/posts');
  }

  public julienne() {
    return this.http.get('https://juliennecosmetic.com/backend/api/products?category=3');
  }
}

我在我的组件上有这个东西。

import { NestedService } from './../services/nested.service';
import { Component, OnInit } from '@angular/core';
import { makeStateKey, TransferState } from '@angular/platform-browser';
import { ActivatedRoute } from '@angular/router';

const USERS_KEY = makeStateKey('products');
const PRODUCTS = makeStateKey('products2');
const JULIENNE = makeStateKey('products3');

@Component({
  selector: 'app-nested',
  template: `
    <p>
      nested worksa asfd safdsa!
    </p>

    <div class="row">
    <div class="col-sm-6 col-md-4 col-lg-3 p-2 mx-auto bg-info" *ngFor="let user of julienne">
    <p>{{user.nombre_comercial}}</p>
    </div>
    </div>

    <div class="row">
    <div class="col-sm-6 col-md-4 col-lg-3 p-2 mx-auto" *ngFor="let user of users">
      {{user.email}}
    </div>
    </div>

    <div class="row">
    <div class="col-sm-6 col-md-4 col-lg-3 p-2 mx-auto" *ngFor="let user of productos">
      <p>{{user.id}}</p>
      <p>{{user.body}}</p>
      <p>{{user.title}}</p>
    </div>
    </div>

  `,
  styles: []
})
export class NestedComponent implements OnInit {
  users;
  productos;
  julienne;

  constructor(
    private nested: NestedService,
    private state: TransferState,
    private aRoute: ActivatedRoute
  ) {}

  ngOnInit() {
    this.users = this.state.get(USERS_KEY, null);
    this.productos = this.state.get(PRODUCTS, null);
    this.julienne = this.state.get(JULIENNE, null);

    if (!this.julienne) {
      this.nested.julienne().subscribe(data => {
        console.log(data);
        this.julienne = data['response']['data'];
        this.state.set(JULIENNE, data['response']['data']);
      });
    }

    if (!this.users) {
      this.nested.getReq().subscribe(data => {
        console.log(data);

        this.users = data['data'];
        this.state.set(USERS_KEY, data['data']);
      });
    }

    if (!this.productos) {
      this.nested.mostrarProductos().subscribe(data => {
        console.log(data);

        this.productos = data;
        this.state.set(PRODUCTS, data);
      });
    }
  }
}

在此工具中,它仅显示生成的https://jsonplaceholder.typicode.com/和要求列表,而在juliennecosmetic.com上则不显示第三个列表。

https://search.google.com/structured-data/testing-tool#url=http%3A%2F%2F31.220.57.15%2Flazy%2Fnested

可能是什么?

3 个答案:

答案 0 :(得分:1)

您正在有效地允许您的组件在不存在的列表上进行迭代,直到API响应为止。

您可以通过几种方式来处理它,这完全取决于用户需求。

  1. 将整件事包裹起来,即
<div *ngIf="users">
... *ngFor="let user of users ...
</div>
  1. 提供空列表开头,因此* ngFor可以进行迭代,但是没有内容。

  2. 切换一个布尔型标志,指示下载阶段已完成,UI现在可以呈现,但这又涉及到直到至少有一个空列表要经过时才到达* ngFor逻辑。

P.S。这是你的问题:)

  

我正在尝试让Angular等待API响应,但我没有   成功。

忘记等待顺序发生的事情时所需要了解的一切,您需要以其他方式适应初始状态,直到发生某些事情为止,例如,不显示表格,显示微调框甚至不显示完全加载该组件。

答案 1 :(得分:1)

也许您应该尝试使用ObservablesPromises和Angular async pipe。另外,由于这是一个异步请求,通常可以在从服务器获取数据之前渲染组件,以便可以添加加载器。

您可以深入研究HttpInterceptor文档来实现加载程序。您可以在this article

中找到一个很好的例子。

答案 2 :(得分:0)

感谢您的评论。

无效的API是“朱丽叶化妆品”。该API托管在共享服务器上的GoDaddy中,它可以检索数据,但是由于某些原因,我仍然在Google上遇到这个问题。

对我来说,解决方法是将API从共享服务器更改为VPS,我在GoDaddy共享服务器端尝试了所有操作,但是没有用,我更改为Ubuntu VPS,它就像reqres和jsonplaceholder一样工作。