Reputation:
I am very new in Angular.. This is my first project and I noticed my function doSomething()
returns a value before it was properly calculated. I looked up async functions but I do not understand how to implement it to my example? Please if someone understands this let me know..
this is my code:
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;
}
Also... The csv results doesn't return international characters.. that is in my other stackoverflow question.. I am a lost cause lol thank you in advance
----------EDIT
I am reading the values here (angular material table):
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 thank you everyone for your kind answers :-) I now understand all this better and it works
Upvotes: 0
Views: 1177
Reputation: 31105
There are multiple things wrong here.
map
operator.application/json
but the reponseType
is text
?Service
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;
}
And in the component, you need to subscribe to it to get the data
Component
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
}
);
}
}
Upvotes: 1
Reputation: 21357
You can use rxjs operators like switchMap, and do some refactoring
doSomething(): Observable<CSVRecord[]> {
let csvList = this.getData().pipe(
switchMap((data) => {
return of(data)
})
)
}
and getData will be changed like this
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;
}));
}
Upvotes: 0
Reputation: 825
No need of doSomething() method. You can use getData() directly.
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;
}
Upvotes: 0