Why XMLHttpRequest works but Angular2+ returns a 404? - ajax

I'm using angular6.
When getHello gets called it returns a 404 error.
import { Injectable } from '#angular/core';
import { HttpClient, HttpHeaders } from '#angular/common/http';
import { Observable, of } from 'rxjs';
import { catchError, map, tap } from 'rxjs/operators';
const httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
#Injectable({ providedIn: 'root' })
export class RequisicaoTransporteService {
constructor(private http: HttpClient) { }
getHello() : Observable<any> {
return this.http.post('http://localhost:17844/api/requisicaotransporte/getHello',{},httpOptions)
};
}
This is how i call it:
this.requisicaoTransporteService.getHello()
.subscribe(x => this.hello = x);
When i do the following, it works fine:
$.ajax({
type: "POST",
url: "http://localhost:17844/api/requisicaotransporte/gethello",
success:function(o){console.log(o);}
});
The server allows CORS.

Related

Angular, error 500 after sending the request in the header

I have a hard time passing the right angular request to the header. This is my service:
import { Injectable } from '#angular/core';
import { HttpClient, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpHeaders }
from '#angular/common/http';
import { Utente } from '../model/Utente ';
import { Prodotto } from '../model/Prodotto ';
import { OktaAuthService } from '#okta/okta-angular';
import { Observable, from } from 'rxjs';
import { Carrello } from '../model/Carrello ';
import { userInfo } from 'node:os';
import { getLocaleCurrencyCode } from '#angular/common';
const headers = new HttpHeaders().set('Accept', 'application/json');
#Injectable({
providedIn: 'root'
})
export class HttpClientService {
constructor(
private httpClient:HttpClient, private oktaAuth:OktaAuthService ) {}
getCarr(){
return this.httpClient.get<Carrello[]>('http://localhost:8080/prodotti/utente/vedicarrelloo', {headers} );
}
}
This is my spring method:
#Transactional(readOnly = true)
public List<Carrello> getCarrello(#AuthenticationPrincipal OidcUser utente){
Utente u= utenteRepository.findByEmail(utente.getEmail());
return carrelloRepository.findByUtente(u);
}
In console I get this error (error 500):
https://i.stack.imgur.com/BiONS.png
this error corresponds in my console to "java.lang.NullPointerException: null.
But if I access localhost: 8080, I can see the answer correctly, so I assume there is a problem in passing the request header in angular, can anyone tell me where am I wrong, please? I specify that I get this error only in the methods where the OidcUser is present, the rest works perfectly. Thank you!
You need to send an access token with your request. Like this:
import { Component, OnInit } from '#angular/core';
import { OktaAuthService } from '#okta/okta-angular';
import { HttpClient } from '#angular/common/http';
import sampleConfig from '../app.config';
interface Message {
date: string;
text: string;
}
#Component({
selector: 'app-messages',
templateUrl: './messages.component.html',
styleUrls: ['./messages.component.css']
})
export class MessagesComponent implements OnInit {
failed: Boolean;
messages: Array<Message> [];
constructor(public oktaAuth: OktaAuthService, private http: HttpClient) {
this.messages = [];
}
async ngOnInit() {
const accessToken = await this.oktaAuth.getAccessToken();
this.http.get(sampleConfig.resourceServer.messagesUrl, {
headers: {
Authorization: 'Bearer ' + accessToken,
}
}).subscribe((data: any) => {
let index = 1;
const messages = data.messages.map((message) => {
const date = new Date(message.date);
const day = date.toLocaleDateString();
const time = date.toLocaleTimeString();
return {
date: `${day} ${time}`,
text: message.text,
index: index++
};
});
[].push.apply(this.messages, messages);
}, (err) => {
console.error(err);
this.failed = true;
});
}
}
On the Spring side, if you want it to accept a JWT, you'll need to change to use Jwt instead of OidcUser. Example here.
#GetMapping("/")
public String index(#AuthenticationPrincipal Jwt jwt) {
return String.format("Hello, %s!", jwt.getSubject());
}

Apollo Graphql with Angular with headers and Subscriptions

I need to add headers to my graphql requests with angular with subscriptions. but I didn't find any way. headers will be added if I only used headers without subscriptions. Also, subscriptions will works if I didn't add headers. But with both, it won't work. here is my code
import { NgModule } from '#angular/core';
import { HttpClientModule } from '#angular/common/http';
import { ApolloModule, Apollo, APOLLO_OPTIONS } from 'apollo-angular';
import { HttpLinkModule, HttpLink } from 'apollo-angular-link-http';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { ApolloLink, split } from 'apollo-link';
import { setContext } from 'apollo-link-context';
import { WebSocketLink } from 'apollo-link-ws';
import { getMainDefinition } from 'apollo-utilities';
const uri = 'http://localhost:5000/graphql';
export function provideApollo(httpLink: HttpLink) {
const basic = setContext((operation, context) => ({
headers: {
Accept: 'charset=utf-8'
}
}));
// Get the authentication token from local storage if it exists
const token = localStorage.getItem('token');
const auth = setContext((operation, context) => ({
headers: {
Authorization: `Bearer ${token}`
},
}));
const subscriptionLink = new WebSocketLink({
uri:
'ws://localhost:5000/graphql',
options: {
reconnect: true,
connectionParams: {
authToken: localStorage.getItem('token') || null
}
}
});
const link = split(({ query }) => {
const { kind } = getMainDefinition(query);
return kind === 'OperationDefinition';
}, subscriptionLink, ApolloLink.from([basic, auth, httpLink.create({ uri })]));
// const link = ApolloLink.from([basic, auth, httpLink.create({ uri }), subscriptionLink]);
const cache = new InMemoryCache();
return {
link,
cache
};
}
#NgModule({
exports: [
HttpClientModule,
ApolloModule,
HttpLinkModule
],
providers: [{
provide: APOLLO_OPTIONS,
useFactory: provideApollo,
deps: [HttpLink]
}]
})
export class GraphQLModule { }
in here headers will not be added. Any Solutions?
This is the solution that I found.
Import below code to your app.module.ts
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { HttpHeaders } from '#angular/common/http';
import { APOLLO_OPTIONS } from "apollo-angular";
import { WebSocketLink } from 'apollo-link-ws';
import { getMainDefinition } from 'apollo-utilities';
import { split } from 'apollo-link';
import { InMemoryCache } from "apollo-cache-inmemory";
import { HttpLink } from 'apollo-angular-link-http';
#NgModule({
imports: [
CommonModule,
],
providers: [
{
provide: APOLLO_OPTIONS,
useFactory(httpLink: HttpLink) {
const http = httpLink.create({
uri: 'http://localhost/v1/graphql',
headers: new HttpHeaders({
"x-hasura-admin-secret": "mysecretkey"
})
})
const ws = new WebSocketLink({
uri: `ws://localhost/v1/graphql`,
options: {
reconnect: true,
connectionParams: {
headers: {
"x-hasura-admin-secret": "mysecretkey"
}
}
}
});
const link = split(
// split based on operation type
({ query }) => {
const definition = getMainDefinition(query);
return (
definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription'
);
},
ws,
http,
);
return {
link,
cache: new InMemoryCache(),
};
},
deps: [HttpLink],
},
]
})
export class GraphqlModule { }
import { NgModule } from "#angular/core";
import { HttpClientModule, HttpHeaders } from "#angular/common/http";
import { ApolloModule, Apollo, APOLLO_OPTIONS } from "apollo-angular";
import { HttpLinkModule, HttpLink } from "apollo-angular-link-http";
import { InMemoryCache } from "apollo-cache-inmemory";
import { ApolloLink, split, from } from "apollo-link";
import { setContext } from "apollo-link-context";
import { WebSocketLink } from "apollo-link-ws";
import { getMainDefinition } from "apollo-utilities";
import ApolloClient from "apollo-client";
const uri = "http://localhost:5000/graphql";
const subscriptionLink = new WebSocketLink({
uri: "ws://localhost:5000/graphql",
options: {
reconnect: true,
connectionParams: {
authToken: localStorage.getItem("token") || null,
},
},
});
const authMiddleware = new ApolloLink((operation: any, forward: any) => {
operation.setContext({
headers: new HttpHeaders().set(
"Authorization",
`Bearer ${localStorage.getItem("token")}` || null,
),
});
return forward(operation);
});
export function createApollo(httpLink: HttpLink) {
return {
link: from([
authMiddleware,
split(
({ query }) => {
const { kind, operation } = getMainDefinition(query);
return kind === "OperationDefinition" && operation === "subscription";
},
subscriptionLink,
httpLink.create({
uri: "http://localhost:5000/graphql",
}),
),
]),
cache: new InMemoryCache(),
};
}
#NgModule({
exports: [HttpClientModule, ApolloModule, HttpLinkModule],
providers: [
{
provide: APOLLO_OPTIONS,
useFactory: createApollo,
deps: [HttpLink],
},
],
})
export class GraphQLModule {}

How wait until complet http request in angular-7

import { Injectable } from '#angular/core';
import { Router } from '#angular/router';
import { HttpClient } from '#angular/common/http';
import { Post } from 'src/app/sign-in/post';
#Injectable({
providedIn: 'root'
})
export class NewUserService {
constructor(private router:Router,private http: HttpClient) { }
async signIn(email:any,password:any){
const userDate = {
email:email,
password:password
}
console.log("Before request");
await this.http.post<{
Status: string;
StatusDetails: string;
token: string;
}>("http://localhost:5000/user/signin", userDate)
.subscribe(respond => {
console.log("respond");
if (respond.token) {
//sign susess
}else {
//fail
}
});
console.log("After request")
}
}
This is my servise.ts class. In hear I try to make a post request. Before completing the request other code execute. I expect output like
Before request
respond
After request
But the actual output is
Before request
After request
respond
How can I execute code like
Before request
respond
After request

Angular UI not updating after data changes

Im new to the MEAN stack and having trouble with getting data changes to be refreshed in the UI. I know the data is getting saved properly in MongoDB, and also retrieved, because when I create a Todo item and I refresh the page, the newly added Todo item appears in the Todo List. The problem is that it isnt happening dynamically.
I've tried a number of different things including NgZone and ChangeDetectorRef to detect changes, not sure what I'm doing wrong..
Let me know if any more info is needed.. thank you!
The Todo List component:
import { Component, Input, OnInit, NgZone } from '#angular/core';
import { Todo } from '../todo.model';
import { TodoService } from '../../todo.service';
#Component({
selector: 'app-todo-list',
templateUrl: './todo-list.component.html',
styleUrls: ['./todo-list.component.scss'],
providers: [TodoService]
})
export class TodoListComponent implements OnInit {
#Input() todos: Todo[] = [];
constructor(private _todoService: TodoService, private zone: NgZone){}
getTodos() {
console.log('todo list - get todos');
this._todoService.getTodos()
.subscribe(resTodoData => {
this.zone.run(() => {
this.todos = resTodoData;
});
});
}
ngOnInit() {
console.log('todo list - init');
this.getTodos();
}
}
Service Component:
import { Injectable, NgZone } from '#angular/core';
import { Http, Response, Headers, RequestOptions } from
'#angular/http';
import { map } from 'rxjs/operators';
import { Todo } from './todos/todo.model';
#Injectable({
providedIn: 'root'
})
export class TodoService {
// these were configured in express server
private _getUrl = "/api/todos";
private _postUrl = "/api/todo";
constructor(private _http: Http, private zone: NgZone) { }
getTodos() {
let json = this._http.get(this._getUrl)
.pipe(map((response: Response) => response.json()));
return json;
}
addTodo(todo: Todo) {
let headers = new Headers({ 'Content-Type': 'application/json'
});
let options = new RequestOptions({ headers: headers });
return this._http.post(this._postUrl, JSON.stringify(todo),
options)
.pipe(map((response: Response) => response.json()));
}
}

How to create authentication in Angular 2 with Laravel Passport?

I have a problem to find way to make authentication for my angular 2 app. I have API in laravel, and tried to use laravel passport(via password grant). I tested it on Postman and now I need to connect it with angular. I've started looking for some library to do it, but i find only this https://github.com/manfredsteyer/angular-oauth2-oidc
Do you have any ideas on how to connect this? I can not cope with that.
You can make service like this , don't forget to assign the client id and secret.
userservice.ts
import {Injectable} from '#angular/core';
import {Observable} from 'rxjs/Rx';
import {Http, Headers, Response} from '#angular/http';
import {User} from './user';
#Injectable()
export class UserService {
constructor(private http: Http) {
}
private oauthUrl = "http://server.techalin.com/oauth/token";
private usersUrl = "http://server.techalin.com/api/users";
getAccessToken() {
var headers = new Headers({
"Content-Type": "application/json",
"Accept": "application/json"
});
let postData = {
grant_type: "password",
client_id: 2,
client_secret: "RGNmOzt7WQ8SdNiCcJKKDoYrsFqI2tudopFjOJU3",
username: "albanafmeti#gmail.com",
password: "password",
scope: ""
}
return this.http.post(this.oauthUrl, JSON.stringify(postData), {
headers: headers
})
.map((res: Response) => res.json())
.catch((error: any) => Observable.throw(error.json().error || 'Server error'));
}
getUsers(accessToken: string): Observable<User[]> {
var headers = new Headers({
"Accept": "application/json",
"Authorization": "Bearer " + accessToken,
});
return this.http.get(this.usersUrl, {
headers: headers
})
.map((res: Response) => res.json())
.catch((error: any) => Observable.throw(error.json().error || 'Server error'));
}
}
and use this service to other component like this
import 'UserService' from './user.service';
export class ExampleCompoent{
constructor(private userService: UserService) {
this.userService.getAccessToken()
.subscribe(data => {
this.getUsers(data.access_token)
});
}
getUsers(accessToken: string) {
this.userService.getUsers(accessToken)
.subscribe(
users => {
this.users = users;
console.log(users);
});
}
}
read more on this link

Resources