-1

I have problem with Http request in Angular CLI. I don't know how to fix this. Is it because of localhost, or is it about browser settings, or is it the openwethermap service? Is it possible to fix this? However, it works when I build the app with ng build command.

A log warning will print this in the console:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the
remote resource at http://api.openweathermap.org/data/2.5/forecast?lat=35&
lon=139&appid=<my_api_key_is_removed_on_stackoverflow>. (Reason: CORS preflight
channel did not succeed).

app.module.ts:

/* Core */
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';

/* Components */
import { AppComponent } from './app.component';
import { FixtureComponent } from './soccer/fixture.component';
import { WeatherComponent } from './weather/weather.component';

/* Interceptors */
import { SoccerAuthInterceptor } from './soccer/soccer.interceptor';

/* Services */
import { WeatherService } from './weather/weather.service';

@NgModule({
  declarations: [
    AppComponent,
    FixtureComponent,
    WeatherComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule
  ],
  providers: [
    WeatherService,
    {
      provide: HTTP_INTERCEPTORS,
      useClass: SoccerAuthInterceptor,
      multi: true
    }
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

weather.servece.ts:

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable, Subject, ReplaySubject, from, of, range } from 'rxjs';
import { map, filter, switchMap } from 'rxjs/operators';

interface Weather {
  message: Number;
  temp: Number;
  temp_min: Number;
  temp_max: Number;
  /* teasdmp: Array<string>; */
}
@Injectable({
  providedIn: 'root'
})
export class WeatherService {
  constructor(private http: HttpClient) { }
  dailyForecast(): Observable<Weather> {
    return this.http.get<Weather>("http://api.openweathermap.org/data/2.5/forecast?lat=35&lon=139&appid=<api_key>").pipe(map(result => result));
  }

  /* private apiUrl = "http://localhost:3000/api/cars";
  getCars(): Observable<Car[]> {
    // tell Angular you are expecting an array of 'Car'
    return this.httpClient.get<Car[]>(this.apiUrl)
  } */
}

weather.component.ts:

import { Component } from '@angular/core';
import { WeatherService } from './weather.service';
import { Chart } from 'chart.js';

@Component({
  selector: 'app-weather',
  template: `
    <div *ngIf="chart">
      <canvas id="canvas">{{ chart }}</canvas>
    </div>`,
  styles: []
})

export class WeatherComponent {

  chart = []; // This will hold our chart info

  constructor(private _weather: WeatherService) { }

  ngOnInit() {
    console.log('test');
    console.log(this._weather.dailyForecast());
    this._weather.dailyForecast()
    .subscribe(res => {
      console.log(res);
      let temp_max = res['list'].map(res => res.main.temp_max);
      let temp_min = res['list'].map(res => res.main.temp_min);
      let alldates = res['list'].map(res => res.dt)

      let weatherDates = []
      alldates.forEach((res) => {
        let jsdate = new Date(res * 1000)
        weatherDates.push(jsdate.toLocaleTimeString('en', { year: 'numeric', month: 'short', day: 'numeric' }))
      })
      this.chart = new Chart('canvas', {
        type: 'line',
        data: {
          labels: weatherDates,
          datasets: [
            {
              data: temp_max,
              borderColor: "#3cba9f",
              fill: false
            },
            {
              data: temp_min,
              borderColor: "#ffcc00",
              fill: false
            },
          ]
        },
        options: {
          legend: {
              display: false
            },
            scales: {
              xAxes: [{
                display: true
              }],
              yAxes: [{
                display: true
              }],
            }
          }
        });
      })
  }
}

Maybe this is the problem? But if so, why does it work when I run the command ng build?

import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http';
import { Observable } from 'rxjs';

export class SoccerAuthInterceptor implements HttpInterceptor {
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const authReq = req.clone({
      headers: req.headers.set('X-Auth-Token', '<api_key>')
    });
    return next.handle(authReq);
  }
}
Mikael S
  • 435
  • 1
  • 4
  • 14
  • Could you share your environment files? and if possible, the typescript code for the http request – Sayegh Apr 26 '18 at 11:03
  • Possible duplicate of [XMLHttpRequest cannot load https://www.\[website\].com/](https://stackoverflow.com/questions/35553500/xmlhttprequest-cannot-load-https-www-website-com) – Quentin Apr 26 '18 at 11:50

1 Answers1

1

If you have a cross origin problem, it is probably the browser complaining about accessing a resource that is not on the same path from which the app was served (and I guess you don't work at and host from openweathermap.org) You need to run an own proxy-server forwarding requests to http://api.openweathermap.org and setting headers for whererever you host your client from. You can do this with SpringBoot and the Netlix Zuul proxy library, for example.

Phil
  • 7,065
  • 8
  • 49
  • 91