繁体   English   中英

Angular 在返回 Observable 之前等待值

[英]Angular wait for value before returning in 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")
  }
}

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

这里有很多错误。

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

服务

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
      }
    );
  }
}

不需要 doSomething() 方法。 您可以直接使用 getData()。

    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[] = [];

      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(): Observable<CSVRecord[]> {
        const userData: CSVRecord[] = [];
        this.getUserData().map(data => {
          data = "\uFEFF"+data
          console.log(data);
          const list = data.split('\n');
            list.forEach( e => {
              const property = e.split(';');

             userData.push({
               name: property[0],
               last_name: property[1],
               postal_code: property[2]
               city: property[3],
               phone: property[4]
             });
            }); 
             return userData;
          }); 

      }

    }

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

你可以使用像 switchMap 这样的 rxjs 操作符,并进行一些重构

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

并且 getData 将像这样更改

getData(): Observable<CSVRecord[]> {
this.userData = [];
return this.getUserData().pipe(map(
 (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 userData;
  })); 
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM