首页 > 解决方案 > Angular 在 Observable 中返回之前等待值

问题描述

我是 Angular 的新手。这是我的第一个项目,我注意到我的函数doSomething()在正确计算之前返回了一个值。我查找了异步函数,但我不明白如何在我的示例中实现它?如果有人明白这一点,请告诉我..

这是我的代码:

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable, of, TimeoutError } from 'rxjs';
import { getLocaleDateFormat } from '@angular/common';

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

  csvPath = "podaci.csv";
  userList: any[] = [];
  userData: CSVRecord[];
  temp = {name:'', last_name:'', postal_code:'', city:'', phone:''};

  constructor(private http: HttpClient) { }

  doSomething(): Observable<CSVRecord[]> {
    let csvList = this.getData();
    return of(csvList);
  }

  getUserData() {
    const headers = new HttpHeaders({'Content-Type':'application/json; charset=utf-8'});
    return this.http.get(this.csvPath, {responseType: 'text'});
  }

  getData(): CSVRecord[] {
    this.userData = [];
    this.getUserData().subscribe(data => {
      data = "\uFEFF"+data
      console.log(data);
      const list = data.split('\n');
        list.forEach( e => {
          const property = e.split(';');
          this.temp = {name:'', last_name:'', postal_code:'', city:'', phone:''};

          this.temp.name = property[0];
          this.temp.last_name = property[1];
          this.temp.postal_code = property[2];
          this.temp.city = property[3];
          this.temp.phone = property[4];

          this.userData.push(this.temp);
        }); 
      }); 
      return this.userData;
  }

}

export interface CSVRecord {
  name: string;
  last_name: string;
  postal_code: string;
  city: string;
  phone: string;
}

另外...... csv结果不返回国际字符..这是我的另一个stackoverflow问题..我是一个失败的原因大声笑提前谢谢你

- - - - - 编辑

我正在阅读这里的值(角度材料表):

import {Component, OnInit, ViewChild} from '@angular/core';
import {MatPaginator} from '@angular/material/paginator';
import {MatTableDataSource} from '@angular/material/table';

import { CSVService, CSVRecord } from './../csv.service';

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

export class TablePaginationExample implements OnInit {
  displayedColumns: string[] = ['name', 'last_name', 'postal_code', 'city', 'phone'];
  dataSource = new MatTableDataSource<CSVRecord>([]);

  @ViewChild(MatPaginator, {static: true}) paginator: MatPaginator;

  constructor(
    private csvService: CSVService
  ) { }

  ngOnInit() {
    this.dataSource.paginator = this.paginator;
  }

  refresh() {
    this.csvService.doSomething().subscribe((data: CSVRecord[]) => {
      this.dataSource.data = data;
    });
  }

  myFunc() {
    console.log("učitaj")
    this.refresh()
  }

  myFunc2() {
    console.log("spremi")
  }
}

----------编辑2谢谢大家的好意回答:-)我现在更好地理解了这一切并且它有效

标签: angulartypescriptasynchronousobservable

解决方案


这里有很多问题。

  1. 对于初学者,您不需要多个不同的函数来将响应从 HTTP 请求映射到另一个。一切都可以用 RxJSmap操作符在同一个函数中完成。
  2. 您声明了一个标头,但从不使用它。
  3. 标头类型 isapplication/jsonreponseTypeis text?

服务

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

import { Observable, of, TimeoutError } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class CSVService {
  csvPath = "podaci.csv";

  constructor(private http: HttpClient) { }

  getUserData(): Observable<CSVRecord[]> {
    const headers = new HttpHeaders({'Content-Type':'application/json; charset=utf-8'});
    return this.http.get(this.csvPath, { headers: headers }).pipe(   // <-- use the headers and omit `responseType` (default is `json`)
      map(data => {
        let result: CSVRecord[] = [];    // <-- should be `let` instead of `const`
        data = "\uFEFF" + data;
        const list = data.split('\n');
        list.forEach(e => {
          const property = e.split(';');
          result.push({
            name: property[0],
            last_name: property[1],
            postal_code: property[2],
            city: property[3],
            phone: property[4],
          });
        });
        return result;
      })
    );
  }
}

export interface CSVRecord {
  name: string;
  last_name: string;
  postal_code: string;
  city: string;
  phone: string;
}

而在组件中,需要订阅它才能获取数据

零件

export class AppComponent implements OnInit {
  userData: CSVRecord[];

  constructor(private csvService: CSVService) { }

  ngOnInit() {
    this.csvService.getUserData().subscribe(
      value => {
        this.userData = value;
      },
      error => {
        // always good practice to handle HTTP observable errors
      }
    );
  }
}

推荐阅读