簡體   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