Angular 6 HttpClient 使用 Map

3

为了学习目的,我正试图从一个JSON假API获取数据,并在返回Observable之前将"hey"添加到所有标题。到目前为止,如果我不使用Map,我可以显示数据,即使使用map,如果我在控制台记录我的变量,它会显示Observable,但它不会在我的模板中显示。

<div class="col-6" *ngIf="courseDatas$ | async as courses else NoData">
  <div class="card" *ngFor="let course of courses">
    <div class="card-body">
      <span><strong>User ID is : </strong>{{course.userId}}</span><br>
      <span><strong>Title is : </strong>{{course.title}}</span><br>
      <span><strong>Body is : </strong>{{course.body}}</span><br>
      <span><strong>ID is : </strong>{{course.id}}</span>
    </div>
    <ng-template #NoData>No Data Available</ng-template>
  </div>
</div>

应用组件:

import {Component, OnInit} from '@angular/core';
import {PostsService} from "./posts.service";

import {Observable} from "rxjs";

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent implements OnInit {
  courseDatas$ : Observable<any>;

  constructor(private posts : PostsService){}


  ngOnInit(){
    this.courseDatas$ = this.posts.getData();

  }
}

文章服务:

import { Injectable } from '@angular/core'
import {HttpClient} from "@angular/common/http";
import {Observable} from "rxjs";
import {map} from "rxjs/operators";

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

  private postURL: string = 'https://jsonplaceholder.typicode.com/posts';

  constructor(private http: HttpClient) {}

  getData(): Observable<any> {
    return this.http.get(this.postURL).pipe(
      map(data => {
        for (let datas of (data as Array<any>)){
          datas.title = datas.title + "Hey";
        }
      }),
    );
  }

因此,如果在我的服务的getData方法中不使用map操作符,则所有内容都能正常显示。如果使用map操作符,如果我在App.Component中控制台查看coursesDatas$,控制台会显示Observable,所以我不理解为什么它在模板中无法与我的async管道一起使用。另外,如果在我的map操作符中使用console.log(datas.title),它确实记录了每个标题,并在末尾加上Hey。


你的映射回调函数实际上没有返回任何东西。你需要使用tap,或者更好的方法(因为它没有副作用),从回调函数中返回一个新数组。 - jonrsharpe
1个回答

8

map应该返回一个可变的当前属性的值,根据您的情况,我猜您应该返回data

getData(): Observable<any> {
    return this.http.get(this.postURL).pipe(
      map(data => {
        for (let datas of (data as Array<any>)){
          datas.title = datas.title + "Hey";
        }
        return data;
      }),
    );
}

顺便提一下,你可以使用Array.prototypemap代替for循环来改变你的数据

getData(): Observable<any> {
    return this.http.get(this.postURL).pipe(
      map(data => data.map(d => (d.title = d.title +"Hey", d));
      }),
    );
 }

请注意,箭头函数中如果省略了花括号,则会自动返回结果。

很高兴了解到自动返回的知识。我忘记了这一点。但是,我无法让 map(data => data.map(d => d.title = d.title +"Hey"); 运行起来。还要感谢你的建议。 - Jean-Philippe Dufour
@Jean-PhilippeDufour 你得到了什么输出? - Artyom Amiryan
@Jean-PhilippeDufour 我已经修复了,请再次检查。 - Artyom Amiryan
工作得很好。谢谢。我有点傻,我甚至没有检查地图的正确实现。 - Jean-Philippe Dufour

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接