How to format my data with modified model in angular - javascript

Hello i am supossed to change the model to the one below but now my code doesnt work and i cant figure out how to format the data with the model provided . Any help appreciated.
here is the api: https://archive-api.open-meteo.com/v1/era5?latitude=51.51&longitude=-0.13&start_date=2005-08-25&end_date=2005-08-25&hourly=temperature_2m,relativehumidity_2m,dewpoint_2m,apparent_temperature,surface_pressure,precipitation,rain,cloudcover,windspeed_10m,winddirection_10m,soil_temperature_0_to_7cm&timezone=Europe%2FLondon
in the component ngOnInit subscription i am making variable for each array of data from the api (modifying some arrays there like time,precipitation and wind direction) and then pushing new WeatherDataItem object with those variables to empty array weatherData: WeatherDataItem[] = [] from which i am filling table columns in html
weatherData: WeatherDataItem[] = [];
…
…
this.weatherService.getWeather()
...
...
.subscribe({
next: (historicalWeatherData) => {
const temperatures = historicalWeatherData.hourly.temperature_2m;
const times = historicalWeatherData.hourly.time.map((time) =>
this.datePipe.transform(time, 'shortTime')
);
const humidities = historicalWeatherData.hourly.relativehumidity_2m;
const windSpeeds = historicalWeatherData.hourly.windspeed_10m;
const airPressures = historicalWeatherData.hourly.surface_pressure;
const windDirections =
historicalWeatherData.hourly.winddirection_10m.map((item) =>
this.checkWindDirection(item)
);
const precipitations = historicalWeatherData.hourly.precipitation.map(
(item) => {
if (item > 0) {
return new Rain(item, true);
}
return new Rain(item, false);
}
);
const cloudcover = historicalWeatherData.hourly.cloudcover;
const soilTemperatures =
historicalWeatherData.hourly.soil_temperature_0_to_7cm;
temperatures.forEach((value, i) => {
this.weatherData.push(
new WeatherDataItem(
value,
times[i],
humidities[i],
windSpeeds[i],
airPressures[i],
windDirections[i],
precipitations[i],
cloudcover[i],
soilTemperatures[i]
)
);
});
...
...
...
here is the model i am using right now for weatherData
export class WeatherDataItem {
constructor(
public temperature: string,
public time: string,
public humidity: string,
public wind: string,
public pressure: string,
public direction: string,
public precipitation: Rain,
public cloudcover: string,
public soilTemperature: string
) {}
}
and i am supposed to use this model because the above one apparently has too many arguments in constructor but dont know how to implement that because now in the component i am getting error: expecting 1 argument but got 9
export class WeatherDataItem {
temperature: number;
time: string;
humidity: number;
wind: number;
pressure: number;
direction: string;
precipitation: Rain;
cloudcover: number;
soilTemperature: number;
constructor(inputData: Object) // type WeatherDataItem ? or what should be the type here
{
(this.temperature = inputData.temperature),
(this.time = inputData.time),
(this.humidity = inputData.humidity),
(this.wind = inputData.wind),
(this.pressure = inputData.pressure),
(this.direction = inputData.direction),
(this.precipitation = inputData.precipitation),
(this.cloudcover = inputData.cloudcover),
(this.soilTemperature = inputData.soilTemperature);
}
}
i tried this in component but no luck
const inputData = [
temperatures,
times,
humidities,
windSpeeds,
airPressures,
windDirections,
precipitations,
cloudcover,
soilTemperatures,
];
this.weatherData.push(new WeatherDataItem(inputData));
html
<p-table
[value]="weatherData"
...
...
...
<ng-template pTemplate="body" let-weather>
<tr>
<td field="time">{{weather.time}}</td>
<td field="temperature">{{weather.temperature}}°C</td>
<td field="humidity">{{weather.humidity}}%</td>
<td field="wind">{{weather.wind}} km/h</td>
<td field="pressure">{{weather.pressure}} hPa</td>
<td field="direction">{{weather.direction}}</td>
<td field="precipitation.didRain">{{weather.precipitation.amount}} mm</td>
<td field="cloudcover">{{weather.cloudcover}}%</td>
<td field="soilTemperature">{{weather.soilTemperature}}°C</td>
</tr>
</ng-template>

it works when I've added it, maybe you've got a typo somewhere. I had to add the mapping to string when creating the new WeatherDataItem in your OnInit function
https://stackblitz.com/edit/angular-ivy-qchu4z

Related

How can I switch value from dataSource (MatTableModule) to other value?

I have a Observable:
getItemInfo(): Observable<Company_item[]> {
return this.db.list<Company_item>(this.API_URL_ITEM).snapshotChanges().pipe(map(response => response.map((item) => this.assignKey(item))));
}
... and current work as:
displayedColumns: string[] = ['billing_date', 'billing_month', 'billing_us', 'billing_vat', 'billing_worker', 'billing_zus', 'company_id', 'key' ];
companyItems$: Observable<Company_item[]> = this.companiesService.getItemInfo();
dataSource = this.companyItems$;
and it's display value on MatTable fine.
I want to switch value of:
getCompaniesInfo(): Observable<Company[]> {
return this.db.list<Company>(this.API_URL_COMPANIES).snapshotChanges().pipe(map(response => response.map((item) => this.assignKey(item))));
}
like:
on company_id value switch to company_name.
My model:
export interface Company {
company_country: string;
company_email: string;
company_name: string;
company_post_code: string;
company_street: string;
company_tax_us_no: string;
company_tax_zus_no: string;
key: string;
}
export interface Company_item {
billing_date: string;
billing_month: string;
billing_us: number;
billing_vat: number;
billing_worker: number;
billing_zus: number;
company_id: number;
key: string;
}
I wrote to this :
getIdInfo(id: string): Observable<Company> {
return this.getCompaniesInfo().pipe(map(res => res.find(re => re['key'] == id) ))
}
and now i have:
getIdInfo$(id: string) {
return this.companiesService.getIdInfo(id).subscribe(res => {
res.company_name}
)
}
and for test to display company_name :
<ng-container matColumnDef="company_id">
<th mat-header-cell *matHeaderCellDef>ID FIRMY</th>
<td mat-cell *matCellDef="let item">{{ item.company_id + getIdInfo$("1") }}
</td>
</ng-container>
But I have to display: 1[object Object]
I should still get the company_id from MatTable to getIdInfo$ function but I don't know how to go about it. How should I do it to make it work well?
I was thinking about forkJoin and displaying the already finished stream in MatTable dataSource but I don't know how to go about it.
As you can see, I'm just starting my programming adventure.
I am very much asking for your support.
I try this:
res: string;
id(id: string): string {
let companyName: string;
this.companiesService.getIdInfo(id).subscribe(res => {
this.res = res.company_name;
companyName = this.res;
console.log(companyName) }, // DISPLAY OK
error => console.log(error)
)
console.log(companyName); //DISPLAY UNDEFINED
return companyName;
}
ngOnInit() {
console.log(this.id("1")) //DISPLAY UNDEFINED
}
But still UNDEFINED

Transformation of Observable

I've a data structure which looks like this:
Observable<Array<LineChart>>
whereby an LineChart is defined like
export interface LineChart {
name?: null | string;
series?: null | Array<DateLineChartEntry>;
}
and an DateLineChartEntry is defined like this:
export interface DateLineChartEntry {
name?: string;
value?: number;
}
where name is string, which contains Date.
For my follow-up operation with this DataStructure i need to convert the DateLineChartEntry to sth. like this:
export interface DateLineChartEntryConverted {
name?: Date;
value?: number;
}
which means, i've to map all DateLineChartEntries like this
DateLineChartEntry => {
name: new Date(name),
value: value
}
My current solutions looks like that:
this.data = getObservable({ body: parameters }).pipe(
map(lca => {
var lcaConverted = [];
for (var lc of lca) {
var name = lc.name
var lcN = {
name: name,
series: []
};
for (var e of lc.series) {
var n = new Date(e.name);
lcN.series.push({
name: n,
value: e.value
});
}
lcaConverted.push(lcN);
}
return lcaConverted;
})
);
Which is pretty ugly and I'm looking for a "nicer" solution to this.
Is there an easy way available to do this by using the initial Observable (and receiving an Observable as output)?
Thanks in advance for your help.
Are you just looking for something a little cleaner? If so look into some of the newer array features instead of writing for:
this.data = getObservable({
body: parameters
}).pipe(
map(lca => lca.map(entry => ({
name: entry.name,
series: entry.series.map(x => ({
name: new Date(x.name),
value: x.value
}))
}))
)
);
Specifically .map: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

Angular 6 ES6 initiate object arrays

I'm really new to javascript.
I have a nested class structure where I need to initiate using a json object. My question is how can I initiate array of EventDate objects and assign to this.dates in CustomerEvents constructor
export default class CustomerEvent {
constructor(customer_event: any) {
this.event_title = customer_event.event_title;
this.customer = customer_event.customer;
this.total_budget = customer_event.total_budget;
this.no_of_people = customer_event.no_of_people;
this.dates = /**array of new EventDate(customer_event.dates) **/;
}
event_title: string;
customer: Customer;
total_budget: number;
no_of_people: number;
dates: EventDate[];
}
class EventDate {
constructor(date: any) {
this.start_date = date.start_date;
this.end_date = date.end_date;
}
start_date: Date;
end_date: Date;
}
If someone could help me on this, it'll be really helpful. Thanks
Just assign new empty array, like this:
constructor(customer_event: any) {
this.event_title = customer_event.event_title;
this.customer = customer_event.customer;
this.total_budget = customer_event.total_budget;
this.no_of_people = customer_event.no_of_people;
this.dates = [];
}
If you need to cast incoming array, you can do this:
...
this.dates = customer_event.dates.map(date => new EventDate(date));
...
Angular Style Guide recommends using interfaces for data model instead of classes:
Consider using an interface for data models.
That being said, you can refactor your code like this:
export interface EventDate {
start_date: Date;
end_date: Date;
}
export interface CustomerEvent {
event_title: string;
customer: Customer;
total_budget: number;
no_of_people: number;
dates: EventDate[];
}
Now when it comes to initialization, you can do it something like this:
const customerEvent: CustomerEvent = {
event_title: 'Some Title',
customer: { /*An Object representing a Customer Type*/ }
total_budget: 123,
no_of_people: 456,
dates: [{
start_date: new Date(),
end_date: new Date()
}]
};
Create those instances yourself:
constructor(customer_event: any) {
this.event_title = customer_event.event_title;
this.customer = customer_event.customer;
this.total_budget = customer_event.total_budget;
this.no_of_people = customer_event.no_of_people;
this.dates = customer_event.dates.map(date => new EventDate(date));
}

Transforme synchronous Map method to async traitment

I have a huge amont of data to transform into new format.
Actually I'm using map method but as it's syncronous and it's affecting performances.
dataFormatted = cmtAllRawdataDB[0].rows.map(elm => new Message(elm, configResult));
For information Message class have globally this format:
export class Data {
public value: string;
public date: Date;
constructor(dbData) {
this.value = '123';
}
}
export class Measure {
public name: string;
public unit: string;
public data: Data[];
constructor(config, dbData) {
this.name = config.name;
this.unit = config.value;
...
this.data = [new Data(dbData)];
}
}
export class Sensor {
public id: string;
public label: string;
public measures: Measure[] = [];
constructor(dbData, config) {
this.id = '123';
this.label = 'SensorType';
config.unitConfig.map(elm => this.measures.push(new Measure(elm, dbData)));
}
}
export class Message {
public id: string;
...
public sensors: Sensor[];
constructor(dbData: any, config: any) {
this.id = dbData.value._id;
....
this.sensors = [new Sensor(dbData, config)];
console.log(this.id, this.arrivalTimestamp);
}
}
Is there a way to run asynchronously this code ?
Just put this operation inside function and put it inside settimeout method, for just 10 millisecond
var example = () => {
setTimeout(() => {
return (dataFormatted = cmtAllRawdataDB[0].rows.map(
elm => new Message(elm, configResult)
));
}, 10);
};
Use async and await keywords like this way
async getDataFormatted(){ return(cmtAllRawdataDB[0].rows.map(elm => new Message(elm, configResult)));
}
let dataFormatted= await getDataFormatted();

how to get specific data inside class?

Let's say I have a data class like below.
export class TestData extends JsonObject {
id: string;
name: string;
sold: {
number: number;
price: number;
total: string;
}
}
And I can receive from my component like so:
myData:TestData = new TestData();
this.myData.name = "Test"
How can i set a data for price inside sold?
Like this :
This assumes that sold is already defined.
this.myData.sold.price = your_price;
If not then
this.myData.sold = {};
this.myData.sold.price = your_price;
I would declare a setter method to mutate your sold object like this:
export class TestData extends JsonObject {
id: string;
name: string;
sold: {
number: number;
price: number;
total: string;
}
setSold: (number, price, total) => {
object.assign({}, this.sold, {number, price, total})
}
}
You can call the method like this:
TestData.setSold(number, number, "string");
Don't forget to instanciate your class using the new keyword before trying to change it.
const testData = new TestData();
testData.setSold(1, 5, "total");
Further information
Object.assign

Categories