angular 2 retrieving a token form an api - javascript

service.ts
This is my service class. I want to request for a token from an API and display it in my console window. Where am I going wrong, the token is not being displayed. May some please help. Thanks
Apart from the token I will want to retrieve some JSON data but first I want to sort out the token.
import {Injectable } from '#angular/core';
import { Http, Response, Headers, RequestOptions} from '#angular/http';
import {Observable} from 'rxjs/Rx';
#Injectable()
export class StartPage{
constructor(public http: Http){}
credential() {
const url = 'https://xxx';
const body = {
"client_id": 'xxx',
"client_secret": 'xxx',
"grant_type": "client_credentials",
"scope": "transportapi:all"
};
let formData: FormData = new FormData();
for (let key in body) {
formData.append(key, body[key]);
}
const headers = new Headers(
{
'Accept': 'application/json'
});
return this.http.post(url, formData, {headers: headers});
}
}
app.component
This is my component class. I want to get a token from an API but the token is not being displayed.
import {Component} from '#angular/core';
import { Http, Headers } from '#angular/http';
import {Observable} from 'rxjs/Rx';
import {StartPage} from '../app/service';
#Component({
selector: 'my-app',
template: '<h1>Hello results {{results.access_token}}</h1>'
,
providers: [StartPage]
})
export class AppComponent{
results:String;
public testing:{};
constructor(public service: StartPage){
}
onSubmit(){
this.service.credential().subscribe(
res => {
this.results = res['access_token'];
console.log(this.results)
}
);
}
}

You are declaring 'results:String', so when you set an object (res['access_token']) is been saved as string....
Try declaring results as any ('results:any')

Related

Angular 9: Uncaught DOMException: Blocked a frame with origin

I just developed sign in authentication for an Angular app and I went to test it. Sign up works just fine. Then I sign out and attempt to sign in and the header does not update as expected, instead I get this error in console:
Uncaught DOMException: Blocked a frame with origin
"chrome-extension://hdokiejnpimakedhajhdlcegeplioahd" from accessing a
cross-origin frame.
at e [as constructor] (chrome-extension://hdokiejnpimakedhajhdlcegeplioahd/lpfulllib.js:1:1441712)
at new e (chrome-extension://hdokiejnpimakedhajhdlcegeplioahd/lpfulllib.js:1:1444920)
at chrome-extension://hdokiejnpimakedhajhdlcegeplioahd/lpfulllib.js:1:1461728
But I am not authenticated because I get:
{authenticated: false, username: null}
authenticated: false
username: null
Even though the GET request itself went through successfully, but there is a problem there, because it's not supposed to be a GET but a POST request. Why does it think it's a GET request?
My signin() method inside my auth service clearly shows it's a post request:
signin(credentials: SigninCredentials) {
return this.http.post(this.rootUrl + "/auth/signin", credentials).pipe(
tap(() => {
this.signedin$.next(true);
})
);
}
Here is my auth http interceptor code:
import { Injectable } from "#angular/core";
import {
HttpEvent,
HttpInterceptor,
HttpHandler,
HttpRequest,
HttpEventType,
} from "#angular/common/http";
import { Observable } from "rxjs";
#Injectable()
export class AuthHttpInterceptor implements HttpInterceptor {
intercept(
req: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
// Modify or log the outgoing request
const modifiedReq = req.clone({
withCredentials: true,
});
return next.handle(modifiedReq);
}
}
Now I do not think the issue is in my AuthHttpInterceptor, I believe the problem is in AuthService:
import { Injectable } from "#angular/core";
import { HttpClient } from "#angular/common/http";
import { BehaviorSubject } from "rxjs";
import { tap } from "rxjs/operators";
interface UsernameAvailableResponse {
available: boolean;
}
interface SignupCredentials {
username: string;
password: string;
passwordConfirmation: string;
}
interface SignupResponse {
username: string;
}
interface SignedinResponse {
authenticated: boolean;
username: string;
}
interface SigninCredentials {
username: string;
password: string;
}
#Injectable({
providedIn: "root",
})
export class AuthService {
rootUrl = "https://api.my-email.com";
signedin$ = new BehaviorSubject(false);
constructor(private http: HttpClient) {}
usernameAvailable(username: string) {
return this.http.post<UsernameAvailableResponse>(
this.rootUrl + "/auth/username",
{
username,
}
);
}
signup(credentials: SignupCredentials) {
return this.http
.post<SignupResponse>(this.rootUrl + "/auth/signup", credentials)
.pipe(
tap(() => {
this.signedin$.next(true);
})
);
}
checkAuth() {
return this.http
.get<SignedinResponse>(this.rootUrl + "/auth/signedin")
.pipe(
tap(({ authenticated }) => {
this.signedin$.next(authenticated);
})
);
}
signout() {
return this.http.post(this.rootUrl + "/auth/signout", {}).pipe(
tap(() => {
this.signedin$.next(false);
})
);
}
signin(credentials: SigninCredentials) {
return this.http.post(this.rootUrl + "/auth/signin", credentials).pipe(
tap(() => {
this.signedin$.next(true);
})
);
}
}
I see you have no HttpHeaders. While I do not see your backend configuration, I suspect the mis configuration causes your exception.
You can update your Angular interpector to something like this:
import {
HttpEvent,
HttpHandler,
HttpHeaders,
HttpInterceptor,
HttpRequest,
} from '#angular/common/http'
import { Injectable } from '#angular/core'
import { Observable } from 'rxjs'
#Injectable()
export class AuthHttpInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// const token = localStorage.getItem('access_token')
// const userToken = localStorage.getItem('id_token')
if (token) {
const authRequest = req.clone({
setHeaders: {
'Content-Type': 'application/json',
// Authorization: `Bearer ${token}`,
// userID: `${userToken}`,
},
})
return next.handle(authRequest)
} else {
const headers = new HttpHeaders({
'Content-Type': 'application/json',
})
const cloned = req.clone({
headers,
})
return next.handle(cloned)
}
}
}
Also make sure that your backend is aligned and headers such as Access-Control-Allow-Origin configured to true
That is caused by LastPass extension. Deactivate it and the error will disappear.

How can I take the data in this service from an HTTP get call?

I have a little issue from an Angular app to get a code from my own server.
I´ve built up a little Spotify App for learning more about Angular 10 and have a little backend that I only use for get the Bearer code to call the Spotify API, but the fact is that in my Angular front I can´t save the code.
Tis is my service call code to the back:
import { Injectable } from '#angular/core';
import { HttpClient, HttpHeaders } from '#angular/common/http';
import { map } from 'rxjs/operators';
import { environment } from '../../environments/environment';
#Injectable({
providedIn: 'root'
})
export class SpotifyService {
token: any;
constructor(private http: HttpClient) {
console.log('Spotify service ready');
this.getAccesToken().subscribe(data => this.token = data['access_token']);
}
getAccesToken(){
return this.http.get(environment.server + `${environment.client_id}/${environment.client_secret}`)
.pipe(
map(res => res)
);
}
getQuery(query: any){
const headers = new HttpHeaders({
'Authorization': `Bearer ${this.token}`
});
const url = `https://api.spotify.com/v1/${query}`;
return this.http.get(url, {headers});
}
I´ve checked the recibed data and I get the request perfectly, but can´t save the data of the suscriber into a variable.
Thanks in advance!
Assuming your component code looks like below, you can make some adjustments and try it.
export class SomeComponent implements OnInit {
spotifyData;
user;
token;
constructor(private spotifyService: SpotifyService, private http: HttpClient) { }
ngOnInit() {
this.user = JSON.parse(localStorage.getItem('user'));
console.log(this.user);
this.token = this.user.token;
this.getSpotifyData();
}
getSpotifyData() {
this.spotifyService.getQuery(this.user, { headers: new HttpHeaders().set('Authorization', 'Bearer ' + this.token) }).subscribe(res => {
console.log(res);
if (res) {
spotifyData = res;
} else {
spotifyData = []
}
});
}

Angular http module - post headers

I'm unable to change the headers when doing a post request with http module in Angular (with Ionic).
Here is my code:
import { Injectable } from '#angular/core';
import { HttpClient, HttpHeaders } from '#angular/common/http';
const apiUrl = "https://webhook.site/c2d56330-84d4-47cf-9f98-472f7eac8000";
#Injectable({
providedIn: 'root'
})
export class APIService {
constructor(private http: HttpClient) { }
getToken(){
var body = {
'data1': 'data2',
'somedata3': 'data4',
};
let headers = new HttpHeaders().append('Content-Type', 'application/json');
this.http.post(apiUrl, JSON.stringify(body), {headers}).subscribe(data =>
console.log(data));
console.log(headers.get('Content-Type')); //return 'application/json'
}
}
Everything works well, but it still sends header "content-type: text/plain" instead of "content-type: application/json".
Do I type something wrong?
I'd prefer something like:
import { HttpHeaders } from '#angular/common/http';
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json'
})
};
this.http.post<Foo>(this.apiUrl, body, httpOptions)
Also I don't see a need to stringify the body, just pass it as a "normal" object

Need to click twice to update server - Angular2

I have a json that is not being update on the first time I click on the button that updates it. The button in question calls this function:
recusaProposta(){
this.propostaService.atualizaDisputa(this.disputa)
.subscribe(
res => this.disputa.propostas_realizadas++,
error => console.log(error)
);
}
Now, at the first time I click on it nothing happens on the json but if I click on it again it does update the field I want (disputa.propostas_realizadas)
Here's the service:
import {Injectable} from '#angular/core';
import {Http, Headers, Response, RequestOptions} from '#angular/http';
import {Component} from '#angular/core';
import {Observable} from 'rxjs/Rx';
import {DisputaPropostaComponent} from './disputas-proposta.component';
import 'rxjs/add/operator/map';
#Injectable()
export class DisputaPropostaService{
contato:Object[] = [];
name: string;
headers:Headers;
url: string = 'http://localhost:3004/disputa';
constructor(private http: Http){}
atualizaDisputa (body:any): Observable<DisputaPropostaComponent[]>{
let bodyString = JSON.stringify(body); // Stringify payload
let headers = new Headers({ 'Content-Type': 'application/json' }); // ... Set content type to JSON
let options = new RequestOptions({ headers: headers }); // Create a request option
return this.http.put(`${this.url}/${body['id']}`, body, options) // ...using post request
.map((res:Response) => res.json()) // ...and calling .json() on the response to return data
.catch((error:any) => Observable.throw(error.json().error || 'Ocorreu um erro em nosso servidor, tente novamente mais tarde')); //...errors if any
}
}
Can you guys help me? Thanks in advance.
The reason is that in your function you return disputa.propostas_realizadas before increasing it by 1. Replace your function with the code below and it should work.
recusaProposta(){
this.propostaService.atualizaDisputa(this.disputa)
.subscribe(
res => ++this.disputa.propostas_realizadas,
error => console.log(error)
);
}

Iterate through an array of objects Angular 2 component

Can anyone help what I am doing incorrect, anything missing?
I am getting undefined for --'this.ack.length'
this._activeChannelService.requestChannelChange(this.selectedchannel.channelName)
.subscribe(
ack => {
this.ack= ack;
console.log(" test: ", this.ack.length);
},
err => {
console.log(err);
});enter code here
ack is of time
ack:Iack[];
Iack has two field of type string. result and message
I need to iterate through array of Iack[] to get the result and message
if message=success then call the another service
service
requestChannelChange (name: string): Observable<Iack[]> {
alert('in servicerequestChannelChange');
let headers = new Headers({'Content-Type': 'application/json'});
let options = new RequestOptions({headers: headers});
let postchannelname = "channelName=" + name;
let requestt = new IRequest(name);
console.log(JSON.stringify(requestt));
return this._http.post(this._activateChangeUrl, JSON.stringify(requestt),{ headers: headers })
//.map(this.extractData)
.map((res:Response) => res.json() as Iack[])
.do(data => console.log("All: " + JSON.stringify(data)))
.catch(this.handleError);
}
You can use observable in your TS service:
import { Injectable } from '#angular/core';
import { IPost } from './IPost';
import { Http, Response, RequestOptions, Headers } from '#angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch';
#Injectable()
export class PostServices {
private _webApiBaseUrl = "http://localhost:62806/v1/Posts"
private _http : Http;
constructor(http : Http){
this._http = http;
}
getAll(): Observable<IPost[]> {
        return this._http.get(this._webApiBaseUrl + '/all', this.getHeaders())
.map((response: Response) => response.json())
.do(data => console.log(`All Data: \n ${ JSON.stringify(data) }`))
.catch(this.handleError);
    }
private handleError(error: Response){
console.error(error);
return Observable.throw(error.json().error || 'Server Error');
}
private getHeaders()
{
let headers = new Headers();
headers.append("Authorization", "");
headers.append("Content-Type", "application/json");
return new RequestOptions({ headers: headers });
}
}
Usage in your TS class:
import { Component, OnInit } from '#angular/core';
import { IPost } from './IPost';
import { PostServices } from './posts.service';
#Component({
selector: 'app-posts',
templateUrl: './posts.component.html',
styleUrls: ['./posts.component.css']
})
export class PostsComponent implements OnInit {
posts: IPost[];
errorMessage: string;
private _postService: PostServices;
constructor(postService: PostServices) {
this._postService = postService;
}
ngOnInit() {
this._postService.getAll()
.subscribe(
data => {this.posts = data; console.log("data.length: " + data.length)}, // here
error => this.errorMessage = <any>error
);
}
}
enter code here is executed before this.ack= ack; is executed
This is a function
ack => {
this.ack= ack;
console.log(" test: ", this.ack.length);
}
that you pass to subscribe(...) and the observable calls it when the data arrives which can take a looong time when it's a call to a server.
enter code here is executed immediately.
You'll have to check for success within the service subscription. An observable is an asynchronous call, so any calls you want to make regarding the data in that async call must be made within it to remain a safe call.
So, make your seconds service call, within the subscription.

Categories