Hello i am trying to learn angular and now hit a wall. So basically what i am trying to do is change weather data for city which is in one component after clicking in home component, in the home component there are 4 cities in a grid and whenever user clicks on either one it redirect him to component with the data (temperature, time, humidity etc) and the data changes based on the city he clicked on the landing home page. Currently the date is fixed to specific date and city. I am very confused on how to make this work and how does this data binding works between components. Can someone help please ?
this is my html weather data component html
<div>
<p-table
#dt
[value]="lazyWeatherData"
dataKey="id"
[columns]="cols"
[scrollable]="true"
[tableStyle]="{ 'min-width': '50rem' }"
scrollHeight="flex"
[globalFilterFields]="['time','temperature','humidity','wind', 'pressure', 'direction', 'precipitation', 'rain', 'cloudcover','soilTemperature']"
[rows]="10"
[paginator]="true"
[lazy]="true"
(onLazyLoad)="loadData($event)"
[loading]="loading"
>
<ng-template pTemplate="caption">
<div *ngIf="filterSwitch" class="flex">
<button pButton label="Clear"
class="p-button-outlined"
icon="pi pi-filter-slash"
(click)="clearFilters(dt)">
</button>
<span >
<i class="pi pi-search"></i>
<input
class="filter-input"
pInputText
type="text"
(input)="dt.filterGlobal($event.target.value, 'contains')" />
</span>
</div>
</ng-template>
<ng-template pTemplate="header" let-columns>
<tr class="icons">
<th
style="min-width:250px"
[pSortableColumn]="col.field"
*ngFor="let col of columns">
<fa-icon [icon]="col.icon"></fa-icon>
{{col.header}}
<p-sortIcon [field]="col.field"></p-sortIcon>
<p-columnFilter
*ngIf="filterSwitch"
[type]="col.type"
display="menu"
[field]="col.field">
</p-columnFilter>
</th>
</ng-template>
<ng-template pTemplate="body" let-lazy let-columns="columns">
<tr>
<td *ngFor="let col of columns">{{ lazy[col.field] + col.value }}</td>
</tr>
</ng-template>
</p-table>
</div>
this is data table TS
export class WeatherDataComponent implements OnInit, OnDestroy {
@ViewChild('dt') table: Table;
showError: string;
weatherData: WeatherDataItem[] = [];
private componentDestroyed$: Subject<boolean> = new Subject();
weatherDataLoading: boolean;
icons: IconDefinition[] = [
faClock,
faTemperatureHigh,
faPercent,
faWind,
faGem,
faDirections,
faWater,
faCloud,
];
cols: WeatherDataCol[];
loading = false;
lazyWeatherData: any = [];
constructor(
private weatherService: WeatherService,
public datePipe: DatePipe
) {
this.cols = [
new WeatherDataCol('time', 'Time', 'text', '', this.icons[0]),
new WeatherDataCol(
'temperature',
'Temperature',
'text',
'°C',
this.icons[1]
),
new WeatherDataCol('humidity', 'Humidity', 'numeric', '%', this.icons[2]),
new WeatherDataCol('wind', 'Wind Speed', 'text', ' km/h', this.icons[3]),
new WeatherDataCol(
'pressure',
'Air Pressure',
'text',
' hPa',
this.icons[4]
),
new WeatherDataCol(
'direction',
'Wind Direction',
'numeric',
'°',
this.icons[5]
),
new WeatherDataCol(
'precipitation',
'Precipitation',
'numeric',
'mm',
this.icons[6]
),
new WeatherDataCol('rain', 'Rain', 'numeric', 'mm', this.icons[6]),
new WeatherDataCol(
'cloudcover',
'Cloudcover',
'numeric',
'%',
this.icons[7]
),
new WeatherDataCol(
'soilTemperature',
'Soil Temperature',
'text',
'°C',
this.icons[1]
),
];
}
ngOnInit(): void {
this.weatherDataLoading = true;
this.weatherService
.getWeatherData()
.pipe(
finalize(() => (this.weatherDataLoading = false)),
takeUntil(this.componentDestroyed$)
)
.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;
const precipitations = historicalWeatherData.hourly.precipitation;
const rain = historicalWeatherData.hourly.rain;
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],
rain[i],
cloudcover[i],
soilTemperatures[i]
)
);
});
},
error: () =>
(this.showError =
'Something went wrong. Please try refreshing the page'),
});
this.loading = true;
}
loadData(event: LazyLoadEvent) {
this.loading = true;
setTimeout(() => {
if (this.weatherData) {
this.lazyWeatherData = this.weatherData.slice(
event.first,
event.first + event.rows
);
this.loading = false;
console.log(this.lazyWeatherData);
}
}, 1000);
}
clearFilters(table: Table) {
table.clear();
}
ngOnDestroy(): void {
this.componentDestroyed$.next(true);
this.componentDestroyed$.complete();
}
}
this is home page component with 4 cities in grid and when user click on either one of them it redirects him to data table above and it should change the data for the city clicked
<div class="container">
<div class="grid">
<a routerLink="/weather-data"><h3>London</h3></a>
<a routerLink="/weather-data"><h3>New York</h3></a>
<a routerLink="/weather-data"><h3>Tokyo</h3></a>
<a routerLink="/weather-data"><h3>Sydney</h3></a>
</div>
this is ts for home
export class HomeComponent implements OnInit {
constructor() {}
ngOnInit(): void {}
}
this is weather service that get data from API
@Injectable({
providedIn: 'root',
})
export class WeatherService {
constructor(private http: HttpClient) {}
getWeatherData(
lat: string = '51.51',
lon: string = '-0.13'
): Observable<WeatherData> {
return this.http.get<WeatherData>(
`https://archive-api.open-meteo.com/v1/era5?latitude=${lat}&longitude=${lon}&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`
);
}
}
basically i need to change the latitude and longitude in the weather service URL based on the city user clicks on , in the homepage which then redirect him to the weather data component with updated data for the city. how can i achieve this ? currently the lat and lon is set default to London