AngularJS: 401 - Unauthorized: HttpInterceptor with Basic Auth - angularjs

I want to call a Rest-Service (Spring MVC) to receive a list of releases. On client side (AngularJs) I use a service creating a HttpClient call. I also have a registered HttpInterceptor to use simple Basic Authentification. The interceptor is provided in app.modules.ts and is called during the rest call.
Unfortunately I get statuscode 401 and I cannot find the 'Authentification' entry in the header. What is missing?
Interceptor:
import { Injectable } from '#angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '#angular/common/http';
import { Observable } from 'rxjs';
#Injectable()
export class BasicAuthInterceptor implements HttpInterceptor {
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
request = request.clone({
setHeaders: {
Authorization: `Basic username:password`
},
});
return next.handle(request);
}
}
Service class:
import { Injectable } from '#angular/core';
import { Observable, of } from 'rxjs/';
import { HttpClient } from '#angular/common/http';
import { catchError, map, tap } from 'rxjs/operators';
import { Release } from './Release';
#Injectable()
export class ReleasesService {
constructor(
private http: HttpClient) {}
private releasesUrl = 'http://localhost:8080/releases/showAll';
getReleases(): Observable<Release[]> {
return this.http
.get<Release[]>(this.releasesUrl)
.pipe( tap(releases => this.log('fetched releases')),
catchError(this.handleError('getReleases', [])));
}
private handleError<T> (operation = 'operation', result?: T) {
return (error: any): Observable<T> => {
console.error(error); // log to console instead
return of(result as T);
};
}
private log(message: string) {
console.info(message);
}
}
app.modules.ts
providers: [
APP_PROVIDERS,
{ provide: HTTP_INTERCEPTORS, useClass: BasicAuthInterceptor, multi: true },
],

I found the solution.
Setting the header was correct. But I had to add following parameter to the HttpClient-call: { withCredentials: true }
getReleases(): Observable<Release[]> {
return this.http
.get<Release[]>(this.releasesUrl, { withCredentials: true })
.pipe( tap(releases => this.log('fetched releases')),
catchError(this.handleError('getReleases', [])));
}
Then the credentials are passed to the server.

Related

Can’t connect Express.js server to the Angular frontend

I created a Node.js application and also an Angular application. I need to get data from the database and also store data to the database. I'm having problems connecting my Express.js server to the Angular application.
File user.service.ts
import { Injectable } from '#angular/core';
import { Observable } from 'rxjs';
import { User } from '../User';
import { HttpClient, HttpHeaders } from '#angular/common/http';
import { BASE_URL } from '../const/config';
import { MONGO_EXPRESS_URL } from '../const/config';
#Injectable({
providedIn: 'root',
})
export class UserService {
constructor(private http: HttpClient) {}
getUsers(): Observable<User[]> {
return this.http.get<User[]>(`${MONGO_EXPRESS_URL}/fetchdata`);
}
}
File users.component.ts
import { Component, OnInit } from '#angular/core';
import { UserService } from 'src/app/services/user.service';
import { User } from '../../User';
#Component({
selector: 'app-users',
templateUrl: './users.component.html',
styleUrls: ['./users.component.css'],
})
export class UsersComponent implements OnInit {
users: User[] = [];
constructor(private userService: UserService) {}
ngOnInit(): void {
this.userService.getUsers().subscribe((users) => (this.users = users));
}
}
This error pops up when I run the Angular application:
File server.js
app.use("/", router);
app.listen(port, function () {
console.log("Server is running on Port: " + port);
});
router.route("/fetchdata").get(function (req, res) {
users.find({}, function (err, result) {
if (err) {
res.send(err);
} else {
res.send(result);
}
});
});
The problem is the route: https://localhost:4000.
It would be http://localhost:4000 (http:// instead of https://).
It should kind of look like this on your Node.js. You should set up the Express.js server like so:
constructor() {
this.app = express()
}
Initialize{
this.app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
res.header('Access-Control-Allow-Methods', 'OPTIONS, GET, POST, PUT');
if('OPTIONS' === req.method){
res.sendStatus(200);
}
else {
next();
}
})
this.app.use(RouterWebservices)
this.app.listen(your.HttpPort, your.Ip, () => {
console.log('Server now listening at ', your.HttpPort, 'IP ', your.Ip);
})
}
Then you need to declare your variables in a router.webservice.ts file:
export const RouterWebservices = express.Router()
RouterWebservices.get('/fetchdata', FetchWebservice)
And write a FetchWebserivce where you simply answer the request with data.

integrated angularjs service

hello every one I had a problem, I create my Ticketservice. this file and I try to add it to the home.ts file but it gives me an error
tickerServices.ts
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root',
})
export class TicketService{
result:any;
constructor(public http: HttpClient) { }
getTicket(){
var CronJob = require('cron').CronJob;
var id=this.formulaire.id;
new CronJob('* * * * * *', function(){
const http = require('http');
console.log('You will see this message every second');
/* this.url+'/'*/
http.get('http://localhost:8888/'+id+'/notif', (resp) => {
let data = '';
// A chunk of data has been recieved.
resp.on('data', (chunk) => {
data += chunk;
this.resulta=data;
});
// The whole response has been received. Print out the result.
resp.on('end', () => {
console.log(data);
});
}).on("error", (err) => {
console.log("Error: " + err.message);
});
}, null, true, 'America/Los_Angeles');
}
}
home.ts
import {Component} from "#angular/core";
import {NavController, PopoverController,NavParams} from "ionic-angular";
import { HttpClient } from '#angular/common/http';
import { TicketService } from '../services/ticketservice'
import 'rxjs/add/operator/map';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
public search = {
date: new Date().toISOString()
}
constructor(public nav: NavController,public http: HttpClient,public popoverCtrl: PopoverController ,public tikSer:TicketService) {
}}
when I test it, he gives me undefined ".. /services/ticketservice"
Add it like this
import { TicketService } from '../../services/ticketservice'

How to use Sql server connection in angular 6?

I have do connection in 'Angular6' using sqlserver.
server.js
var express = require('express');
var app = express();
app.get('/', function (req, res) {
var sql = require("mssql");
// config for your database
var config = {
user: 'abc',
password: 'abc',
server: 'servername',
database: 'xyz'
};
// connect to your database
sql.connect(config, function (err) {
if (err) console.log(err);
// create Request object
var request = new sql.Request();
// query to the database and get the records
request.query('select * from tbl', function (err, recordset) {
if (err) console.log(err)
// send records as a response
res.send(recordset);
});
});
});
var server = app.listen(5000, function () {
console.log('Server is running..');
});
data.service.ts
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Injectable({
providedIn: 'root'
})
export class DataService {
constructor(private http: HttpClient) { }
getUsers() {
return this.http.get('https://jsonplaceholder.typicode.com/users')
}
getUser(userId) {
return this.http.get('https://jsonplaceholder.typicode.com/users/'+userId)
}
getPosts() {
return this.http.get('https://jsonplaceholder.typicode.com/posts')
}
getPhotos()
{
return this.http.get('https://jsonplaceholder.typicode.com/photos');
}
getTodos()
{
return this.http.get('https://jsonplaceholder.typicode.com/todos');
}
}
Right now I have used dummy API'S for result.
how to get my database results in service?
I have successfully get result from Sqlserver database.
I also want to display record in my Component
user.component.html
<h1>Users</h1>
Can I have to import server.js in user.component.ts.
If yes than how can I do that?
I think you are misunderstanding angular. Angular run into browser and its context is limited to that.
If you need to connect to a database, you need to use some backend technologies, like express and nodejs, as the code you posted.
The main way is to expose some backend services, like REST services, developed with a server side techonology (nodejs, j2ee, php, etc) and then use Angular to ask them for data.
Generally to achieve this goal in angular you should use HttpClient
You should search for a tutorial, like this
Angular example to request data
In angular you should create a service class to call your exposed service, then into that class you could create a method like this:
import {HttpClient, HttpHeaders} from '#angular/common/http';
import {Observable} from 'rxjs';
import {Injectable} from '#angular/core';
import {catchError, map, tap} from 'rxjs/operators';
#Injectable({
providedIn: 'root'
})
export class TestService {
get(): Observable<any> {
return this.http.get([YOUR_BACKEND_SERVICE_URL]).pipe(
catchError(this.handleError(`get`))
);
}
private handleError<T>(operation = 'operation', result?: T) {
return (error: any): Observable<T> => {
console.error(error);
this.log(`${operation} failed: ${error.message}`);
return of(result as T);
};
}
}
Then you should write a component like this:
#Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.css']
})
export class TestComponent implements OnInit {
data: any;
constructor(private testService: TestService) { }
ngOnInit() {
this.getData();
}
getData(): void {
this.testService.get().subscribe(data => console.log(data));
}
}
You need to create service and component with AngularCli in order to avoid to manually declare and import them into app.module.ts
For a better understanding of what is happening I suggest you to read Angular Tour of Heroes tutorial, Services section

How I use "Interval" or similar on an Http Observable?

I'm fairly new to AngularJS (2.0.0-beta.16). I've managed to setup a service that pulls data from an API, via a GET request. Now, how do I set it up to run the GET request every n seconds? I've seen other posts saying you could just using this._http.get(...).interval(5000).map(...);, however when I've tried that, I get a Typescript compilation error:
Property 'interval' does not exist on type 'Observable'.
Am I making a silly mistake or is there a better pattern for doing this?
import { Injectable } from 'angular2/core';
import { Http, Response } from "angular2/http";
import { Observable } from "rxjs/Observable";
import * as _ from "js/lodash.js";
import { Foo } from "./foo";
#Injectable()
export class FooService {
fooList: Observable<Foo[]>;
constructor(private _http: Http) {
this.fooList = this._http.get('http://localhost:9090/api/').map(
response => {
var json = response.json();
if(response.ok === true) {
let newFooList: Foo[] = [];
_.forEach(json, f => {
newFooList.push(new Foo(f));
});
return newFooList;
}
throw Error("Bad status: " + response);
});
}
}
This is probably not the only (or the best) way, but it worked for me. The only issue is that the first GET request is delayed by the amount of time specified by create().
import { Injectable } from "angular2/core";
import { Http, Response } from "angular2/http";
import { Observable } from "rxjs/Observable";
import { IntervalObservable } from "rxjs/observable/IntervalObservable";
import * as _ from "js/lodash.js";
import { API_URI } from "./constants";
import { Foo } from "./foo";
#Injectable()
export class FooService {
public fooList: Observable<Foo[]>;
constructor(private _http: Http) {
this.fooList = IntervalObservable.create(2000).flatMap(
() => {
return this._http.get(API_URI);
}).map(
response => {
var json = response.json();
if(response.ok === true) {
let newFooList: Foo[] = [];
_.forEach(json, f => {
newFooList.push(new Foo(f));
});
return newFooList;
}
throw Error("Bad status: " + response);
});
}
}

Returning http response from a angular 2 service

I have the following code for my service
import {Injectable} from 'angular2/core';
import {Http} from 'angular2/http';
import {Response} from "angular2/http";
import {PRIVATE_SERVERS} from "../mock/private_servers_list";
import 'rxjs/Rx';
/*import {PRIVATE_SERVERS} from "../mock/private_servers_list";*/
#Injectable()
export class PrivateServerService {
http= null;
PRIVATE_SERVERS = null;
constructor(http:Http){
this.http = http;
}
logError(err){
console.log("some error");
}
getPrivateServers(){
this.http.get('http://private-server.eviry.com/get_private_servers')
.map(res => res.json())
.subscribe(
data => this.PRIVATE_SERVERS = data, //printing data here gives me the correct value
err => this.logError(err),
() => console.log('Private Server fetching complete')
);
console.log(this.PRIVATE_SERVERS);
return this.PRIVATE_SERVERS;
}
}
I have injected this service in to a component called private-server.component. Basically, in this service I am trying to get a list of private servers using the url http://private-server.eviry.com/get_private_servers
I access this url in getPrivateServers() function. When I print the response within the subscribe method, I can see the data fetched correctly.
However, when I try to console.log(this.PRIVATE_SERVERS), it prints null. Is this the correct way to use the angular service or is there a way to make it wait for the response?
The assignment happens in an asynchronous callback. If you want to use its value outside that callback, you need to wait for it to complete.
You can also use Event Emitter to react asynchronous to the response.
Here is an good introduction to Observables in Angular2.
PrivateServerService.ts
import { Injectable } from 'angular2/core';
import { Http } from 'angular2/http';
import { Response } from "angular2/http";
import { PRIVATE_SERVERS } from "../mock/private_servers_list";
import 'rxjs/Rx';
/*import {PRIVATE_SERVERS} from "../mock/private_servers_list";*/
#Injectable()
export class PrivateServerService {
PRIVATE_SERVERS = null;
constructor(private http: Http) {
this.setPrivateServerMocksData();
}
logError(err) {
console.log("some error");
}
getPrivateServers() {
return this.http.get('http://private-server.eviry.com/get_private_servers')
.map(res => res.json());
}
setPrivateServerMocksData() {
this.getPrivateServers()
.subscribe((data) => {
this.PRIVATE_SERVERS = data
console.log(this.PRIVATE_SERVERS);
},
(err) => {
this.logError(err)
});
}
}
YourComponent.ts
getPrivateServerInfo() {
this.privateServerService.getPrivateServers()
.subscribe((data) => {
//you have your data here to work with
console.log(data);
},
(err) => {
this.logError(err)
});
}

Resources