I am trying to run this application in my local but not working.Many times i tried but i could not find the issue.I think api url issue.If i run this application i am getting below the error.How to resolve this issue? How can i run this application without error?
zone.js:2935 GET http://salembrothers.ca/app/api/getSettings/social 404 (Not Found)
products:1 Access to XMLHttpRequest at 'http://salembrothers.ca/app/api/getSettings/social' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
For full code : https://github.com/MarouaneSH/Angular-6-Shopping-cart-with-Laravel
api.service.ts:
import { HttpClient , HttpParams } from '#angular/common/http';
import { Injectable } from '#angular/core';
import { catchError } from 'rxjs/operators/catchError';
import { ErrorObservable } from 'rxjs/observable/ErrorObservable';
import { Observable } from 'rxjs/Rx'
const apiUrl = "http://salembrothers.ca/app/api";
#Injectable()
export class ApiService {
constructor(private http:HttpClient) { }
get(path,params:HttpParams = new HttpParams()){
return this.http.get(`${apiUrl}/${path}`, {params})
.pipe(
catchError(this.handleError)
);
}
post(path,params){
return this.http.post(`${apiUrl}/${path}`, params)
.pipe(
catchError(this.handleError)
);
}
handleError(err:any){
return Observable.throw(err);
}
}
As the error message says 'has been blocked by CORS policy', you need to enable CORS in your API server, your API server/framework may also require to whitelist your 'http://localhost:4200' where you are running Angular.
Related
I have tho following angular service:
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { Observable } from 'rxjs';
import { person } from '../interfaces/iperson';
import { item } from '../interfaces/iitem';
#Injectable({
providedIn: 'root'
})
export class PeopleserviceService {
constructor(private http: HttpClient) { }
getPersonData(): Observable<person[]> {
return this.http.get<person[]>('/assets/data/people.json');
}
completeTransaction(p: person, i: item){
return this.http.get<person[]>('/assets/data/people.json').toPromise().then(peopleData => {
if (!peopleData) {
return Promise.reject(new Error('No data received'));
}
for (const pers of peopleData) {
if (pers.id === p.id) {
pers.balance -= i.price;
break;
}
}
return this.http.put('/assets/data/people.json', JSON.stringify(peopleData)).toPromise();
});
}
}
but it gives the following error:
ERROR Error: Uncaught (in promise): HttpErrorResponse: {"headers":{"normalizedNames":{},"lazyUpdate":null},"status":404,"statusText":"Not Found","url":"http://127.0.0.1:4200/assets/data/people.json","ok":false,"name":"HttpErrorResponse","message":"Http failure response for http://127.0.0.1:4200/assets/data/people.json: 404 Not Found","error":"<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<title>Error</title>\n</head>\n<body>\n<pre>Cannot PUT /assets/data/people.json</pre>\n</body>\n</html>\n"}
Angular 17
core.mjs:9171:22
Angular 2
RxJS 6
Angular 14
How would I make this angular page running locally write to a file?
I have looked into the localforage package, but that doesn't seem to work.
assets/data/people.json lives on the server. When you are one Localhost, the client and the server are on the same computer, but usually the server is somewhere remote.
You cannot just write into a file on a server, if you want to do that you have to create a backend (i.e. NodeJS with Express) and create an endpoint that accepts some data, then on the Server you can write data on your file.
Keep in mind that this file is share with all the user, it's not a personal copy.
I have an angular application and the client wants the path of the Backend in a json file, so he can change it easily whithout needing of another deployment.
Well i did it, but when i refresh the page or close the app and reopen it, the app don't detect the path of the backend, it is like a problem of retard or synchronisation.
This is the error in the console :
http://***/undefinedapi/Leave/GetlistLeave
This is how i did it :
The json file :
{
"ApiRoot": "http://***/"
}
How i read from the constant from the json file :
import { Injectable } from '#angular/core';
import { Http, Response } from '#angular/http';
import { Observable } from 'rxjs';
import { apiRoot } from '../model/model.apiRoot';
import { map } from 'rxjs/operators';
#Injectable({
providedIn: 'root'
})
export class apiRootService {
static apiRoot: string;
constructor(private http: Http) { }
public initialiseApiRoot()
{
this.http.get('./assets/apiRoot/apiRoot.json').pipe(map((response: Response) =>
<apiRoot>response.json())).subscribe(data => {
apiRootService.apiRoot = data['ApiRoot'];
})
}
}
and then i call this function in the constructor of app.component.ts like this :
this.apiRootService.initialiseApiRoot();
and change the call of the api in every servic elike this :
return this.http.get(apiRootService.apiRoot + .....
Any hlp and thanks
Well, let's suppose you're not facing a cache problem. If it isn't a cache problem, maybe it's a matter of timing.
You can try to set your apiRoot while your app is initializing (before app.component.ts is loaded). You can do that by providing an APP_INITIALIZER as described in Angular docs. If you use a factory that returns a function providing a promise, you'll delay your app initialization until your json file is loaded so you can initialize apiRoot. A factory is a useful approach because it will allow you to inject HttpClient service during initialization in the provider (you'll need it to get your json file).
You can do something like (in your app.module.ts):
...
import {APP_INITIALIZER} from '#angular/core';
...
// Angular will inject the HttpClient because you'll
// tell it that this is a dependency of this factory
// in the providers array
export function getApiRoot(http: HttpClient) {
return () => {
return this.http.get('./assets/apiRoot/apiRoot.json').pipe(
map((response: Response) => <apiRoot>response.json()),
tap((data: any) => apiRootService.apiRoot = data['ApiRoot'])
).toPromise();
};
}
...
#NgModule({
imports: [
...
HttpClientModule,
...
],
providers: [
...
{
provide: APP_INTIALIZER,
useFactory: getApiRoot,
multi: true,
deps: [HttpClient]
}
...
]
})
export class AppModule {}
because you are going with wrong approach. you are seeting url after application is initialized. Refer :- https://medium.com/voobans-tech-stories/multiple-environments-with-angular-and-docker-2512e342ab5a. this will give general idea how to achieve build once and deploy anywhere
I am new to Angular 6, and I am having one issue with custom header for Authorisation. I am setting a Oauth2 token in Authorisation header but it is not going along with request. I have done a lot of googling but none of the solution solves my problem. Below I am adding code.
Custom header in request:
getCurrentUser() {
let token = this.cookie.get('token');
return this.http.get<User[]>(serverurl + 'getUser',{
headers: new HttpHeaders().set('Authorization', token),
}) // this.httpOptions
.pipe(
tap(user => this.log(`fetched current user`)),
catchError(this.handleError('currentUser', []))
);
}
As request Interceptor:
import { AuthService } from '../services/auth.service';
import { Injectable } from '#angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpHeaders } from '#angular/common/http';
import { Observable } from 'rxjs';
import { CookieService } from 'ngx-cookie-service';
#Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(private auth: AuthService, private cookie: CookieService) { }
intercept(req: HttpRequest<any>, next: HttpHandler) {
let token = this.cookie.get('token');
let changedRequest = req;
// HttpHeader object immutable - copy values
const headerSettings: { [name: string]: string | string[]; } = {};
if (token) {
headerSettings['Authorization'] = 'Bearer ' + token;
}
// headerSettings['Content-Type'] = 'application/json';
const newHeader = new HttpHeaders(headerSettings);
changedRequest = req.clone({
headers: newHeader
});
return next.handle(changedRequest);
}
}
It gives following request:
Authorisation token is added in Access-control-request-Header instead of Authorisation itself. And I don't see Authorisation header in request.
Thanks in Advance...!
After searching a lot for this I found the solution for this:
There is no problem in the code, since you are using Cross Origin request it first sent OPTIONS request to the server. In order to fix this I added following piece of code in my server configuration section:
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
It has nothing to do with Angular 6. Basically you need to Allow OPTIONS method for all URLs from server side. And it will work. :)
I am new to angular 6 and trying to do api calls with the help of proxy from the following link.
angular 6 proxy configuration for api call
but I failed to get response from the server and it shows following error in terminal
[HPM] Error occurred while trying to proxy request /api/file2.php from localhost:4200 to http://localhost:1234 (ECONNREFUSED (https://nodejs.org/api/errors.html#errors_common_system_errors)
service.ts
import { Injectable } from '#angular/core';
import { HttpClient,HttpHeaders } from '#angular/common/http';
interface myData{
obj:Object;
}
#Injectable({
providedIn: 'root'
})
export class RecordsService {
constructor(private http:HttpClient) {
this.recordFunc();
}
recordFunc() {
let headers=new HttpHeaders();
return this.http.get<myData>('/api/file2.php');
}
}
proxyconfig.json
{
"/api":{
"target":"http://localhost:1234",
"secure":false,
"changeOrigin":true
}
}
I can't understand what the issue is here.I followed the instructions as per in the video.
I have searched about it in google, Yes I understood that am receiving context/type:text/html not application/json,but I didn't get how to solve this issue. when I trying to hit the api of third party user from my local server , am getting this error. Please check the screenshot of this error.
service.ts
export class VamosysService {
constructor(private _http:Http){}
getVechicalLocations():Observable<any[]>{
return this._http.get(API_URL)
.pipe(map((response:Response)=<any[]>response.json()));
}
component.ts
export class VamosysComponent implements OnInit {
vechicalLocation:any[];
constructor(private _vamoService:VamosysService) { }
ngOnInit() {
this._vamoService.getVechicalLocations()
.subscribe((data) => this.vechicalLocation = data);
}
}
Thanks in advance
You are using HttpModule which is deprecated you should use HttpClientModule instead
In new HttpClientModule JSON is an assumed default and no longer needs to be explicitly parsed using res.json()
Service
import { HttpClient } from '#angular/common/http';
export class VamosysService {
constructor(private _httpc:HttpClient){}
getVechicalLocations():Observable<any[]>{
return this._httpc.get(API_URL);}
Component
export class VamosysComponent implements OnInit {
public vechicalLocation=[];
constructor(private _vamoService:VamosysService) { }
ngOnInit() {
this._vamoService.getVechicalLocations()
.subscribe((data) => this.vechicalLocation=data);
}}
In Case if you are Requesting non-JSON data
you can use the responseType property.
getVechicalLocations():Observable<any[]>{
return this._httpc.get(API_URL,{ responseType: 'text' });}
response type could be responseType?: 'arraybuffer' | 'blob' | 'json' | 'text'
I had a similar error when getting a string back from the response. My error was:
error: {error: SyntaxError: Unexpected token W in JSON at position 0 at JSON.parse () at XMLHttp…, text: "We've just sent you an email to reset your password."}
And I don't have control over the actual response. However, I found this in the documentation which specifically sets that you can be expecting non-JSON responses. So you would have something like
return this._http.get(API_URL, {responseType: 'text'}) // Notice the additional parameter here
.pipe(map((response:Response)=<any[]>response.json()));
I notice you're also specifically parsing json after though, so it would be depending on the actual response on how you want to handle it.
According to your STACKBLITZ. The api that you have used is not working properly. If it changed to working get api call it is working properly. WORKING demo with different test api call.
and instead of using Http I'm suggesting you to use HttpClient with additional benefits.
The HttpClient in #angular/common/http offers a simplified client HTTP
API for Angular applications that rests on the XMLHttpRequest
interface exposed by browsers. Additional benefits of HttpClient
include testability features, typed request and response objects,
request and response interception, Observable apis, and streamlined
error handling.
Then you no need explicitly parsed into json inside map. And also it will return a observable type. You could just consume the return json after subscribe to it.
Before you can use the HttpClient, you need to import the Angular HttpClientModule (into root AppModule).
Sample AppModule code:
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { HttpClientModule } from '#angular/common/http';
#NgModule({
imports: [
BrowserModule,
// import HttpClientModule after BrowserModule.
HttpClientModule,
],
declarations: [
AppComponent,
],
bootstrap: [ AppComponent ]
})
export class AppModule {}
Then import HttpClient inside your VamosysService
import { HttpClient } from '#angular/common/http';
Try to use getVechicalLocations() like below
constructor(private _http: HttpClient) { }
getVechicalLocations(){
return this._http.get(API_URL);
}
Hope this helps to you!