I have a service to connect to my backend. But I have this problem:
The error:
ERROR in src/app/login/sevices/login.service.ts(18,14): error TS2345: Argument of type '(res: Response) => Promise' is not assignable to parameter of type '(value: Response, index: number) => Promise'.
Types of parameters 'res' and 'value' are incompatible.
Type 'Response' is not assignable to type 'Response'. Two different types with this name exist, but they are unrelated.
Property 'body' is missing in type 'Response'.
login.service.ts:
import {Injectable} from "#angular/core";
import { Http } from '#angular/http';
import { Observable } from 'rxjs/Observable';
import { Login } from'../data-login/models/login.model';
import 'rxjs/add/operator/catch';
#Injectable()
export class LoginService{
private url = 'http://localhost:8080/login';
constructor(private http: Http){}
loginQuery(login: Login){
return this.http.post(this.url,JSON.stringify(login))
.map((res:Response) => res.json())
.catch((error:any) => Observable.throw(error.json().error || 'Server error'));
}
}
My Component:
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import { LoginService } from '../sevices/login.service';
import { Login } from './models/login.model';
import {NgForm} from "#angular/forms";
import {AuthService} from "../../auth.service";
#Component({
selector: 'data-login-component',
templateUrl: './data-login.component.html',
styleUrls: ['./data-login.component.css']
})
export class DataLoginComponent implements OnInit {
cssClass: string;
login: Boolean = false;
constructor(private loginService: LoginService, private router: Router, private authService: AuthService) { }
ngOnInit() {
}
verifyLogin(change: Boolean){
if(change){
console.log('OK');
this.authService.login();
this.router.navigate(['home-aluno']);
}else{
console.log('ERROR');
}
}
onSingin(form: NgForm){
if( (form.value.code !== '') && (form.value.password !== '')){
this.loginService.loginQuery(new Login(form.value.code, form.value.password))
.subscribe(
result => this.verifyLogin(result)
);
}
}
}
My backend working fine. Where is my problem?
Related
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());
}
A good practice given by Cypress (e2e testing) is to set the state of the app programmatically rather than using the UI. This of course makes sense.
On this video https://www.youtube.com/watch?v=5XQOK0v_YRE Brian Mann propose this solution to expose a Redux store :
Is there any possibility with NGXS to have access to the different state programmatically during testing ? An example is for the login process : dispatching directly a Login action or setting the store with the access token, to be logged in before any test, would be nice.
This cofnfiguration works for me:
in app folder in model:
export interface IWindowCypress {
Cypress: {
__store__: Store;
};
}
in app.module.ts:
import {BrowserModule} from '#angular/platform-browser';
import {NgModule} from '#angular/core';
import {NgxsModule, Store} from '#ngxs/store';
import {AppComponent, IWindowCypress} from './app.component';
import {ZooState} from './state/zoo.state';
import {NgxsReduxDevtoolsPluginModule} from '#ngxs/devtools-plugin';
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule, NgxsModule.forRoot([ZooState], {}),
NgxsReduxDevtoolsPluginModule.forRoot()
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {
constructor(protected store: Store) {
const windowSore: IWindowCypress = window as unknown as IWindowCypress;
if (windowSore.Cypress) {
console.log('ustawiĆem store');
windowSore.Cypress.__store__ = store;
}
}
}
using in app component:
import {Component} from '#angular/core';
import {Store} from '#ngxs/store';
import {FeedAnimals} from './state/zoo.state';
/// <reference types="Cypress" />
export interface IWindowCypress {
Cypress: {
__store__: Store;
};
}
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'cypress-ngxs';
constructor() {
const windowSore: IWindowCypress = window as unknown as IWindowCypress;
if (windowSore.Cypress) {
(windowSore.Cypress.__store__ as Store).dispatch(new FeedAnimals());
}
}
}
using in cypress spec:
/// <reference types="Cypress" />
import {Store} from '#ngxs/store';
import {IWindowCypress} from 'src/app/app.component';
import {FeedAnimals, ZooState} from '../../../src/app/state/zoo.state';
import {Observable} from 'rxjs';
describe('My Second Test Suite', () => {
it('My FirstTest case', () => {
cy.visit(' http://localhost:4200/ ');
cy.get('.content > :nth-child(2)').should(item => {
const windowSore: IWindowCypress = window as unknown as IWindowCypress;
if (windowSore.Cypress) {
// get store
const store: Store = windowSore.Cypress.__store__;
// declare observable
const myObs: Observable<boolean> = store.select(ZooState.zoo$);
// subscribe
myObs.pipe().subscribe((feed) => console.log('from subscribe: ', feed));
// make some dispatch
(windowSore.Cypress.__store__ as Store).dispatch(new FeedAnimals());
(windowSore.Cypress.__store__ as Store).dispatch(new FeedAnimals());
(windowSore.Cypress.__store__ as Store).dispatch(new FeedAnimals());
(windowSore.Cypress.__store__ as Store).dispatch(new FeedAnimals());
}
});
});
});
and zoo state:
import {Injectable} from '#angular/core';
import {Action, Selector, State, StateContext} from '#ngxs/store';
export class FeedAnimals {
static readonly type = '[Zoo] FeedAnimals';
}
export interface ZooStateModel {
feed: boolean;
}
#State<ZooStateModel>({
name: 'zoo',
defaults: {
feed: false
}
})
#Injectable()
export class ZooState {
#Selector()
static zoo$(state: ZooStateModel): boolean {
return state.feed;
}
#Action(FeedAnimals)
feedAnimals(ctx: StateContext<ZooStateModel>): void {
console.log('fedeeeeeed');
const state = ctx.getState();
ctx.setState({
...state,
feed: !state.feed
});
}
}
Since creating a new angular 6 project, some previous code that I've copied over doesn't seem to be working. This primarily seems to be rxjs syntax
On the .map, it displays the error:
[ts] Property 'map' does not exist on type 'Observable'<User>'.
I seem to be getting a similar error on another file with .take
Is anyone able to point me in the right direction to resolve this please?
import { Injectable } from '#angular/core';
import { ActivatedRouteSnapshot, RouterStateSnapshot, CanActivate, Router } from '#angular/router';
import { Observable } from 'rxjs';
import { AngularFireAuth } from 'angularfire2/auth';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/take';
import 'rxjs/add/operator/do';
#Injectable()
export class LoginGuardService implements CanActivate {
constructor(
private router: Router,
private auth: AngularFireAuth
) { }
canActivate(): Observable<boolean> {
return this.auth.authState.map(authState => {
if (authState) this.router.navigate(['/folders']);
return !authState;
}).take(1);
}
}
Second Guard
canActivate(route:ActivatedRouteSnapshot, state:RouterStateSnapshot):
Observable<boolean> {
this.authGuardStateURL = state.url;
return this.auth.authState.pipe(
take(1)
.map(authState => !!authState)
.do(auth => !auth ? this.router.navigate(['/login']) : true)
)
}
I reckon you used Angular CLI to create your app. Angular 6 comes with RxJS 6 and since v5, RxJS has been using pipeable operators.
So your code should look like this:
import { Injectable } from '#angular/core';
import { ActivatedRouteSnapshot, RouterStateSnapshot, CanActivate, Router } from '#angular/router';
import { Observable } from 'rxjs';
import { AngularFireAuth } from 'angularfire2/auth';
import { map, take, tap } from 'rxjs/operators';
#Injectable()
export class LoginGuardService implements CanActivate {
constructor(
private router: Router,
private auth: AngularFireAuth
) { }
canActivate(): Observable<boolean> {
return this.auth.authState.pipe(
map(authState => {
if (authState) this.router.navigate(['/folders']);
return !authState;
}),
take(1)
)
}
//Second Guard
canActivate(route:ActivatedRouteSnapshot, state:RouterStateSnapshot): Observable<boolean> {
this.authGuardStateURL = state.url;
return this.auth.authState.pipe(
take(1),
map(authState => !!authState),
tap(auth => !auth ? this.router.navigate(['/login']) : true)
)
}
}
Notice how you import the operators now and how you put map and take inside pipe method.
I'm trying to use the isBrowser function in angular universal but I keep getting the same error when I build. I did install the npm package of angular-universal
npm i angular2-universal --save
'ng build -prod -aot'
ERROR in Illegal state: symbol without members expected, but got {"filePath":"C:/dir/universal/website/node_modules/#angular/platform-browser/platform-browser.d.ts","name":"__platform_browser_private__","members":["BROWSER_SANITIZATION_PROVIDERS"]}.
ERROR in ./src/main.ts
Module not found: Error: Can't resolve './$$_gendir/app/app.module.ngfactory' in 'C:/dir/universal/website\src'
# ./src/main.ts 4:0-74
# multi ./src/main.ts
this is my app.module.ts:
//modules
import { HomeModule } from './home/home.module';
import { IntakeFormulierModule } from './intake-formulier/intake-formulier.module';
import { BrowserModule } from '#angular/platform-browser';
import { UniversalModule } from 'angular2-universal/browser';
import { NgModule } from '#angular/core';
//routing
import { routing } from "./app.routing";
//pages
import { AppComponent } from './app.component';
//isbrowser
import { isBrowser } from 'angular2-universal';
#NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule.withServerTransition({
appId: 'website-u - (starter)'
}),
HomeModule,
IntakeFormulierModule,
routing,
],
providers: [
{ provide: 'isBrowser', useValue: isBrowser }
],
bootstrap: [AppComponent]
})
export class AppModule { }
this is my app/home/landing/landing.ts
import { Component, Inject } from '#angular/core';
import { Router } from '#angular/router';
#Component({
...
})
export class LandingComponent {
constructor(//public updateTop: TopImageUpdateService,
public router: Router,
#Inject('isBrowser') public isBrowser: boolean) {}
navigateToResults(name) {
if (this.isBrowser) {
let scrollToTop = window.setInterval(() => {
let pos = window.pageYOffset;
if (pos > 0) {
window.scrollTo(0, pos - 10); // how far to scroll on each step
} else {
window.clearInterval(scrollToTop);
this.router.navigate(['home/page', name]);
}
}, 9)
}
}
}
It looks like they are using isPlatformBrowser() instead of isBrowser() in the angular universal example.
https://github.com/angular/universal#universal-gotchas
import { Component, Inject, PLATFORM_ID, OnInit } from '#angular/core';
import { isPlatformBrowser, isPlatformServer } from '#angular/common';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements {
constructor(
#Inject(PLATFORM_ID) private platformId: Object
){
}
ngOnInit(){
if (isPlatformBrowser(this.platformId)) {
//Client only code.
} else {
//Server only code.
}
}
}
I am building a basic CRUD application in Angular2. However I am having some issues while running tests of components.
Component Code:
///<reference path="../../node_modules/angular2/typings/browser.d.ts"/>
import { Component, OnInit } from 'angular2/core';
import { RouteParams, Router, ROUTER_DIRECTIVES } from 'angular2/router';
import { EmployeeEditFormComponent } from './employee-edit-form.component';
import { EmployeeDetailServiceComponent } from '../services/employee-detail-service.component';
import { EmployeeDeleteServiceComponent } from '../services/employee-delete-service.component';
#Component({
selector: 'employee-detail',
templateUrl: 'src/pages/employee-detail.component.html',
providers: [
EmployeeDetailServiceComponent,
EmployeeDeleteServiceComponent
],
directives: [ ROUTER_DIRECTIVES, EmployeeEditFormComponent ]
})
export class EmployeeDetailComponent implements OnInit {
public currentEmployee;
public errorMessage: string;
constructor(
private _router: Router,
private _routeParams: RouteParams,
private _detailService: EmployeeDetailServiceComponent,
private _deleteService: EmployeeDeleteServiceComponent
){}
ngOnInit() {
let id = parseInt(this._routeParams.get('id'));
this._detailService.getEmployee(id).subscribe(
employee => this.currentEmployee = employee,
error => this.errorMessage = <any>error
);
}
deleteHandler(id: number) {
this._deleteService.deleteEmployee(id).subscribe(
employee => this.currentEmployee = employee,
errorMessage => this.errorMessage = errorMessage,
() => this._router.navigate(['EmployeeList'])
)
}
}
Spec Code:
/// <reference path="../../typings/main/ambient/jasmine/jasmine.d.ts" />
import {
it,
describe,
expect,
TestComponentBuilder,
injectAsync,
setBaseTestProviders,
beforeEachProviders
} from "angular2/testing";
import {
Response,
XHRBackend,
ResponseOptions,
HTTP_PROVIDERS
} from "angular2/http";
import {
MockConnection,
MockBackend
} from "angular2/src/http/backends/mock_backend";
import {
TEST_BROWSER_PLATFORM_PROVIDERS,
TEST_BROWSER_APPLICATION_PROVIDERS
} from "angular2/platform/testing/browser";
import {
Component,
provide
} from "angular2/core";
import {
RouteParams
} from 'angular2/router';
import 'rxjs/Rx';
import { Employee } from '../models/employee';
import { EmployeeDetailComponent } from './employee-detail.component';
import { EmployeeEditFormComponent } from './employee-edit-form.component';
import { EmployeeDetailServiceComponent } from '../services/employee-detail-service.component';
import { EmployeeDeleteServiceComponent } from '../services/employee-delete-service.component';
class MockDetailService{
public getEmployee (id: number) {
return new Employee(1, "Abhinav Mishra");
}
}
class MockDeleteService{
public deleteEmployee (id: number) {
return new Employee(1, "Abhinav Mishra");
}
}
describe('Employee Detail Component Tests', () => {
setBaseTestProviders(
TEST_BROWSER_PLATFORM_PROVIDERS,
TEST_BROWSER_APPLICATION_PROVIDERS
);
beforeEachProviders(() => {
return [
HTTP_PROVIDERS,
provide(XHRBackend, {useClass: MockBackend}),
provide(RouteParams, { useValue: new RouteParams({ id: '1' }) }),
provide(EmployeeDetailServiceComponent, {useClass: MockDetailService}),
provide(EmployeeDeleteServiceComponent, {useClass: MockDeleteService})
]
});
it('should render list', injectAsync([TestComponentBuilder], (tcb: TestComponentBuilder) => {
return tcb
.overrideProviders(EmployeeDetailComponent,
[
provide(EmployeeDetailServiceComponent, {useClass: MockDetailService}),
provide(EmployeeDeleteServiceComponent, {useClass: MockDeleteService})
]
)
.createAsync(EmployeeDetailComponent).then((componentFixture) => {
componentFixture.detectChanges();
expect(true).toBe(true);
});
}));
});
I keep getting following error:
Error: XHR error (404 Not Found) loading http://localhost:9876/angular2/router
at error (/home/abhi/Desktop/angular2-testing/node_modules/systemjs/dist/system.src.js:1026:16)
at XMLHttpRequest.xhr.onreadystatechange (/home/abhi/Desktop/angular2-testing/node_modules/systemjs/dist/system.src.js:1047:13)
at XMLHttpRequest.wrapFn [as _onreadystatechange] (/home/abhi/Desktop/angular2-testing/node_modules/angular2/bundles/angular2-polyfills.js:771:30)
at ZoneDelegate.invokeTask (/home/abhi/Desktop/angular2-testing/node_modules/angular2/bundles/angular2-polyfills.js:365:38)
at Zone.runTask (/home/abhi/Desktop/angular2-testing/node_modules/angular2/bundles/angular2-polyfills.js:263:48)
at XMLHttpRequest.ZoneTask.invoke (/home/abhi/Desktop/angular2-testing/node_modules/angular2/bundles/angular2-polyfills.js:431:34)
Would be great to have some feedbacks.