I have metronic_v5.5.2 Angular Version and I am trying to integrate Its angular version with my backend API.
As I am pretty new to all this, Now the issue is with my proxy configuration that is not working according to my expectations.
The following is the code of proxyconfig.json file
{
"/api": {
"target": "https://localhost:5001",
"secure": false,
"changeOrigin": true,
"logLevel": "debug"
}
}
But In browsers' console this request is actually routing to the URL http://localhost:4200/api/auth/login which return 401 error. I am unable to route on clicking of button to the url: https://localhost:5001/api/auth/login
Following is the HTML Code
<!--begin::Form-->
<form class="m-login__form m-form" name="form" (ngSubmit)="f.form.valid && submit()" #f="ngForm" novalidate>
<div class="form-group">
<mat-form-field>
<mat-label>Email</mat-label>
<input matInput type="email" name="email" placeholder="Email address" autocomplete="off" [(ngModel)]="model.email" #email="ngModel" email="true" required>
</mat-form-field>
</div>
<div class="form-group">
<mat-form-field>
<mat-label>Password</mat-label>
<input matInput minlength="4" type="password" name="password" placeholder="Password" autocomplete="off" [(ngModel)]="model.password" #password="ngModel" required>
</mat-form-field>
</div>
</form>
<!--end::Form-->
<!--begin::Action-->
<div class="m-login__action m-login__action--fit">
<a href="javascript:;" (click)="forgotPasswordPage($event)" class="m-link">
<span translate="AUTH.GENERAL.FORGOT_BUTTON">Forgot Password?</span>
</a>
<m-spinner-button [options]="spinner" (click)="submit()">{{'AUTH.LOGIN.BUTTON' | translate}}</m-spinner-button>
</div>
Following is the login.component.ts code
submit() {
this.spinner.active = true;
if (this.validate(this.f)) {
this.authServiceDb.logindb(this.model).subscribe(response => {
this.router.navigate(['/']);
this.alertify.success('Logged In Successfully');
this.spinner.active = false;
this.cdr.detectChanges();
}, error => {
this.alertify.error(error);
});
}
}
function the code for authdb exported class is given blow, Edit
import { Injectable } from '@angular/core';
import { Http, Headers, RequestOptions, Response } from '../../../node_modules/@angular/http';
import { map, catchError } from 'rxjs/operators';
import { throwError } from '../../../node_modules/rxjs';
import { tokenNotExpired, JwtHelper } from 'angular2-jwt';
@Injectable({
providedIn: 'root'
})
export class AuthdbService {
baseUrl = 'api/auth/';
userToken: any;
decodedTokenn: any;
jwtHelper: JwtHelper = new JwtHelper();
constructor(private http: Http) { }
public logindb(model: any) {
return this.http.post(this.baseUrl + 'login', model, this.requestOptions()).pipe(map((response: Response) => {
const user = response.json();
if (user) {
localStorage.setItem('token', user.tokenString);
this.decodedTokenn = this.jwtHelper.decodeToken(user.tokenString);
this.userToken = user.tokenString;
}
})).pipe(catchError(this.handleError));
}
register(model: any) {
return this.http.post(this.baseUrl + 'register', model, this.requestOptions()).pipe(catchError(this.handleError));
}
loggedIn() {
return tokenNotExpired('token');
}
private requestOptions() {
const headers = new Headers({
'Content-type': 'application/json'});
return new RequestOptions({headers: headers});
}
private handleError(error: any) {
const applicationError = error.headers.get('Application-Error');
if (applicationError) {
return throwError(applicationError);
}
const serverError = error.json();
let modelStateErrors = '';
if (serverError) {
for (const key in serverError) {
if (serverError[key]) {
modelStateErrors += serverError[key] + '\n';
}
}
}
return throwError(
modelStateErrors || 'Server Eroor'
);
}
}
And In My package.json I have the following code
{
"name": "default",
"version": "0.0.0",
"license": "MIT",
"scripts": {
"ng": "ng",
"start": "ng serve --proxy-config proxyconfig.json",
"build": "ng build --prod",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
"private": true,
"dependencies": {
"@angular/animations": "^6.1.0",
"@angular/cdk": "^6.4.0",
"@angular/common": "^6.1.0",
"@angular/compiler": "^6.1.0",
"@angular/forms": "^6.1.0",
"@angular/http": "^6.1.0",
"@angular/platform-browser": "^6.1.0",
"@angular/platform-browser-dynamic": "^6.1.0",
"@angular/platform-server": "^6.1.0",
"@angular/router": "^6.1.0",
"@kolkov/angular-editor": "^0.10.3",
"@ng-bootstrap/ng-bootstrap": "^2.2.0",
"@ngx-loading-bar/core": "^2.1.1",
"@ngx-translate/core": "^10.0.2",
"@types/lodash": "^4.14.112",
"alertifyjs": "^1.11.1",
"angular-in-memory-web-api": "^0.6.0",
"angular2-jwt": "^0.2.3",
"chart.js": "^2.7.2",
"classlist.js": "^1.1.20150312",
"core-js": "^2.5.7",
"hammerjs": "^2.0.8",
"lodash": "^4.17.10",
"material-design-icons": "^3.0.1",
"ng2-charts": "^1.6.0",
"ngx-auth": "4.0.0",
"ngx-highlightjs": "^2.0.4",
"ngx-perfect-scrollbar": "^6.2.0",
"ngx-permissions": "^5.0.0",
"object-path": "^0.11.4",
"rxjs-compat": "^6.2.2",
"rxjs-tslint": "^0.1.5",
"web-animations-js": "^2.3.1",
"zone.js": "^0.8.26"
},
"devDependencies": {
"@angular-devkit/build-angular": "^0.7.0",
"@angular/cli": "^6.0.8",
"@angular/compiler-cli": "^6.1.0",
"@angular/core": "^6.1.0",
"@angular/language-service": "^6.1.0",
"@angular/material": "^6.4.0",
"@angular/material-moment-adapter": "^6.4.0",
"@types/jasmine": "^2.8.8",
"@types/jasminewd2": "^2.0.3",
"@types/node": "^10.5.2",
"codelyzer": "^4.4.2",
"jasmine": "^3.1.0",
"jasmine-core": "^3.1.0",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~2.0.4",
"karma-chrome-launcher": "^2.2.0",
"karma-coverage-istanbul-reporter": "^2.0.1",
"karma-jasmine": "^1.1.2",
"karma-jasmine-html-reporter": "^1.2.0",
"moment": "^2.22.2",
"protractor": "^5.3.2",
"rxjs": "^6.2.2",
"ts-node": "^6.0.3",
"tslint": "~5.9.1",
"typescript": "2.7.2"
}
}
It took me a couple of hours to fix incorrect routing of POST /api/auth/login to https://localhost:5001 which is in the image you provided.
Following config fixes the routing of POST /api/auth/login to https://localhost:5001/api/auth/login.
{
"/api": {
"target": "https://localhost:5001/api",
"changeOrigin": true,
"logLevel": "debug",
"pathRewrite": { "^/api" : "" }
}
}
You said you are new to this, so let me explain something simple first.
When you call http.post the first parameter is the url that will be contacted. So:
this.http.post(this.baseUrl + 'login', ...
will become
this.http.post('api/auth/login', ...
because you set baseUrl and added 'login':
baseUrl = 'api/auth/';
But your code does not say which protocol to use (http or https) NOR which domain:port to call (eg. http://mydomain:port/api/auth/login).
Therefore Angular will default to 'http' and to the domain and port that IT is using, which is localhost:4200. So your request then becomes:
http://localhost:4200/api/auth/login
That is why you see that in the console. Angular is completely ignoring your proxy file. I think the reason is either the name, or location (it should normally be in your project's root folder) or you have not told Angular to load it.
You need to tell Angular to actually use it when it starts up. So in package.json you need something like this:
"start": "ng serve --proxy-config proxyconfig.json"
This tells Angular-CLI that when you use the npm run start
(or just npm start
) command to start the app, it should load the proxy data from that json file in the root folder.
I would advise reading this tutorial also.
Also, I think you have /*
missing from your proxyconfig:
{
"/api/*": {
"target": "http://localhost:5001",
"secure": false,
"changeOrigin": true,
"logLevel": "debug"
}
}
I had this same issue and adding proxyConfig
option to the serve target did the job.
Go to angular.json -> within serve add the key:value pair "proxyConfig": "proxy.conf.json"
like this -
"architect": {
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "your-application-name:build",
"proxyConfig": "proxy.conf.json"
},
btw, I got this from here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With