I have json data coming in from a URL. The data looks like this:
[
{"id":1,"symbol":"SP-500","date":"1927-12-30T07:00:00.000+00:00","open":17.66,"high":17.66,"low":17.66,"close":17.66,"volume":0},
{"id":2,"symbol":"SP-500","date":"1928-01-03T07:00:00.000+00:00","open":17.76,"high":17.76,"low":17.76,"close":17.76,"volume":0}
]
The code to retrieve it is in quote.service.ts and looks like this:
getQuotesList(): Observable<any> {
return this.http.get(`${this.baseUrl}`);
}
Here is the whole class:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, Subject } from 'rxjs';
import { of } from 'rxjs';
import 'rxjs/add/operator/map'
import 'rxjs/operator/filter';
import { Quote } from "./quote";
@Injectable({
providedIn: 'root'
})
export class QuoteService {
private baseUrl = 'http://localhost:8080/springboot-crud-rest/api/v1/quotes';
constructor(private http: HttpClient) { }
getQuote(id: number): Observable<any> {
return this.http.get(`${this.baseUrl}/${id}`);
}
createQuote(quote: Object): Observable<Object> {
return this.http.post(`${this.baseUrl}`, quote);
}
updateQuote(id: number, value: any): Observable<Object> {
return this.http.put(`${this.baseUrl}/${id}`, value);
}
deleteQuote(id: number): Observable<any> {
return this.http.delete(`${this.baseUrl}/${id}`, { responseType: 'text' });
}
//getQuotesList(): Observable<any> {
// return this.http.get(`${this.baseUrl}`);
//}
getQuotesList(): Observable<[string[], string[]]> {
// replace of(data) to this.http.get(this.baseUrl)
return of(data).pipe(
map((quotes) => {
return quotes.reduce((acc, curr) => {
acc[0].push(curr.date.substr(0, 10));
acc[1].push(curr.open);
return acc;
}, [[], []]);
}),
)
}
}
The data is then sent on to quote-list.component.ts which successfully loads it into the quotes array like this:
export class QuoteListComponent implements OnInit {
quotes: Observable<Quote[]>;
It then passes quotes on to quote-list.component.html and builds a table using the following code:
<tr *ngFor="let quote of quotes | async">
<td>{{quote.symbol}}</td>
<td>{{quote.date}}</td>
<td>{{quote.open}}</td>
<td>{{quote.high}}</td>
<td>{{quote.low}}</td>
<td>{{quote.close}}</td>
<td>{{quote.volume}}</td>
<td><button (click)="deleteQuote(quote.id)" class="btn btn-danger">Delete</button>
<button (click)="quoteDetails(quote.id)" class="btn btn-info" style="margin-left: 10px">Details</button>
</td>
</tr>
The table looks nice and all the data is there.
Now I want to load it into a separate array for each value, like this:
[1927-12-30,1928-01-03]
[17.66,17.76]
etc.
And then I want to make those arrays available to a javascript charting program which will plot the data. That plotting code requires a separate array for each value.
I thought that if I modified quote.service.ts to look something like
getQuotesList(): Observable<any> {
let quotes = this.http.get(`${this.baseUrl}`);
let opens = quotes.map(theOpen => open);
console.log("opens.length=" + opens.length);
opens.forEach(function(item,index,array) {
console.log(item,index);
})
return quotes;
}
But get the error:
ERROR in quote.service.ts:38:23 - error TS2339: Property 'map' does not exist on type 'Observable<Object>'. 38 let opens = quotes.map(theOpen => open);
So I changed getQuotesList(): Observable<any> to getQuotesList(): Observable<Quote[]>
But got the following error:
ERROR in quote.service.ts:38:23 - error TS2339: Property 'map' does not exist on type 'Observable<Object>'. 38 let opens = quotes.map(theOpen => open); ~~~ quote.service.ts:43:4 - error TS2322: Type 'Observable<Object>' is not assignable to type 'Observable<Quote[]>'. The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead? Type 'Object' is missing the following properties from type 'Quote[]': length, pop, push, concat, and 26 more.
So I changed let opens = quotes.map(theOpen => open); to let opens = quotes.pipe(map(theOpen => open));
But got the error
ERROR in quote.service.ts:39:40 - error TS2339: Property 'length' does not exist on type 'Observable<(url?: string, target?: string, features?: string, replace?: boolean) => Window>'.
39 console.log("opens.length=" + opens.length);
~~~~~~
quote.service.ts:40:18 - error TS2345: Argument of type '(item: any, index: any, array: any) => void' is not assignable to parameter of type '(value: (url?: string, target?: string, features?: string, replace?: boolean) => Window) => void'.
40 opens.forEach(function(item,index,array) {
Then I tried:
getQuotesList() {
let quotes = this.http.get<Quote[]>(`${this.baseUrl}`);
let opens = quotes.pipe(map(theOpen => open));
alert(opens[0]);
return quotes;
}
But the output was "undefined"
Then I tried
private quoteObserver = {
next(quote) {
console.log("quote.open=" +quote.open);
}
}
getQuotesList() {
let quotes = this.http.get<Quote[]>(`${this.baseUrl}`);
of(quotes).subscribe(this.quoteObserver);
return quotes;
}
but the output was quote.open=undefined
Then I tried
getQuotesList(): Observable<any> {
let quotes = this.http.get(`${this.baseUrl}`);
quotes.subscribe(arr => {
Object.values(arr[0].forEach(el => {
let col = arr.map(ele => ele[el]);
console.log(el,':', col);
}
)}
return quotes;
}
But the error was
ERROR in quote.service.ts:67:6 - error TS1005: ',' expected.
67 )}
~
quote.service.ts:68:5 - error TS1005: ',' expected.
68 return quotes;
~~~~~~
ERROR in quote.service.ts:64:23 - error TS2339: Property 'map' does not exist on type 'Object'.
64 let col = arr.map(ele => ele[el]);
Do you think I've made enough attempts yet? :-( I'm new to Angular/Typescript so hoping someone can guide me.
EDIT: I managed to figure how to port the code over to a linux server. Now you can access the back end to see the actual data coming in by entering this in the browser: 167.172.141.34:8080/springboot-crud-rest/api/v1/quotes