Unexpected token e in JSON at position 0 Angular 12 .Net 5 - node.js

I am getting really weird behavior trying to call the Controller in .net 5 MVC project from the angular 12.
I am getting 200 status code and even get the data that I suppose to get but at the same response I am getting the error message **"Unexpected token e in JSON at position 0"**.enter image description here
I am able to use the postman and call the controller with no problem so that makes me think the problem is with the Angular.
Here is how my angular side looks like:
data.service.ts:
import { Injectable } from '#angular/core';
import { HttpClient, HttpHeaders } from '#angular/common/http';
import { Token } from './models/token';
import { Observable } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class DataService{
constructor(private http: HttpClient) { }
getEco(input:string):Observable<string>{
return this.http.get<string>(`home/${input}`,{ headers: this.headers});
}
getToken(): Observable<Token> {
return this.http.post<Token>("token/generate", {headers: this.headers })
}
private headers: HttpHeaders = new HttpHeaders({ 'Content-Type': 'application/json' });
component:
import { Component, OnInit } from '#angular/core';
import { DataService } from './data-service.service';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'ClientApp';
constructor(private dataService: DataService){}
ngOnInit(): void {
this.dataService.getEco("ahanahui").subscribe((res) =>{
console.log(res);
});
this.dataService.getToken().subscribe(res => console.log(res));
}
}

I was missing the NewtonsoftJson that would serialize response for me newtonsoft.com/json
public static class ConfigurationExtensions
{
public static IServiceCollection ConfigureMVC(this IServiceCollection services)
{
services.AddNewtonsoftJson(options =>
{
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
options.SerializerSettings.ContractResolver = new DefaultContractResolver();
});
return services;
}
}

Related

New Entry Not reflacting in table after inserting New record in CRUD angular app

In Angular 13, I created basic CRUD app of employee. When i insert new data and hit submit it run the createEmployee() service and print data on console. Then it redirect to home page that shows all entry in table which call getEmployeeList(). But sometimes it shows newly created entry and sometimes it not shows. In database it perfectly entered. When i goto some other page and come back to home page it shows.
create-employee.components.ts
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import { Employee } from 'src/app/employee';
import { EmployeeService } from 'src/app/Services/employee.service';
#Component({
selector: 'app-create-employee',
templateUrl: './create-employee.component.html',
styleUrls: ['./create-employee.component.css']
})
export class CreateEmployeeComponent implements OnInit {
employee: Employee = new Employee();
constructor(private employservice: EmployeeService,private router: Router) { }
ngOnInit(): void {
}
saveEmployee() {
this.employservice.createEmployee(this.employee).subscribe(data => {
console.log(data);
})
console.error();
}
gotoemployeelist() {
this.router.navigate(['employees']);
}
onSubmit() {
this.saveEmployee();
this.gotoemployeelist();
}
}
employee-service.ts
import { HttpClient } from '#angular/common/http';
import { Injectable } from '#angular/core';
import { map, Observable } from 'rxjs';
import { Employee } from '../employee';
#Injectable({
providedIn: 'root'
})
export class EmployeeService {
public baseURL="http://localhost:8080/api/v1/employees";
constructor(private httpClient: HttpClient) {}
getEmployeeList(): Observable<Employee[]> {
return this.httpClient.get<Employee[]>(this.baseURL).pipe(
map(employees => {
for(let employee of employees) {
employee.bdate = new Date(employee.bdate);
employee.jdate = new Date(employee.jdate);
}
console.log("Employees Service: GetEmployee() called");
return employees;
}));
}
createEmployee(employee: Employee): Observable<Object> {
console.log("Employees Service: CreateEmployee() called");
return this.httpClient.post(this.baseURL,employee);
}
getEmployeebyId(id: Number): Observable<Employee> {
console.log("Employees Service: GetEmployeeById() called");
return this.httpClient.get<Employee>(this.baseURL+"/"+id);
}
updateEmployee(employee: Employee,id: number): Observable<Object> {
console.log("Employees Service: UpdateEmployee() called");
console.log(employee);
return this.httpClient.put(this.baseURL+"/"+id,employee);
}
deleteEmployee(id: number): Observable<Object> {
console.log("Employees Service: DeleteEmployee() called");
return this.httpClient.delete(this.baseURL+"/"+id);
}
}
Home-component.ts
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import { Employee } from 'src/app/employee';
import { EmployeeService } from 'src/app/Services/employee.service';
#Component({
selector: 'app-employee-list',
templateUrl: './employee-list.component.html',
styleUrls: ['./employee-list.component.css',]
})
export class EmployeeListComponent implements OnInit {
employees: Employee[];
constructor(private employeeservice: EmployeeService,private router: Router) {
}
ngOnInit(): void {
this.getEmployees();
}
private getEmployees() {
this.employeeservice.getEmployeeList().subscribe(data => {
console.log(data);
this.employees=data;
});
}
updateEmployee(id: Number) {
this.router.navigate(['update-employee',id]);
}
deleteEmployee(id: number) {
this.employeeservice.deleteEmployee(id).subscribe(data => {
console.log(id+"employeed Deleted.");
this.getEmployees();
});
}
employeeDetails(id: number) {
this.router.navigate(['emloyee-details',id]);
}
}
In console you can see that createEmployee() called then GetEmployee() called and then it print console.log(newEntry) after navigation.
What is happening program is not waiting to complete createEmployee API before navigating to the home page. You need to call gotoemployeelist() only after the you get response from createEmployee API. You can do this by calling the method inside the subscribe
saveEmployee() {
this.employservice.createEmployee(this.employee).subscribe(data => {
console.log(data);
this.gotoemployeelist();
})
console.error();
}
gotoemployeelist() {
this.router.navigate(['employees']);
}
onSubmit() {
this.saveEmployee();
}

Logout button functionality in mean stack ,how to make the session expire?

i have been working on a project as intern and is new to mean stack
this is the issue i am facing ,
i have been asked to create a login page that is done , but the catch is the login is authenticated by the company side . So basically in my login component the following logic is what i have implemented.
login.component.ts file’s component goes like the following
onSubmit(event) {
event.preventDefault()
console.log('value',this.loginForm.value)
if(this.errorMail.length === 0) {
this.loginService.login(this.loginForm.value).subscribe((res:any) => {
console.log('login response', res)
if(res.auth.success === true) {
localStorage.setItem('auth', JSON.stringify(res.auth))
this.loginService.loggedIn$.next(res.auth)
this.router.navigateByUrl('/search/list')
} else {
this.errorMail='Email or password is not valid'
}
})
}
the following is login.service.ts
import { Injectable } from '#angular/core';
import {HttpClient} from '#angular/common/http'
import { BehaviorSubject } from 'rxjs';
interface LoginResponse {
success: boolean
}
#Injectable({
providedIn: 'root'
})
export class LoginService {
constructor(private http: HttpClient) { }
loggedIn$ = new BehaviorSubject(null)
login(creds) {
// console.log('creds',creds)
return this.http.post<LoginResponse>('url-of-company', {creds})
}
and in my header component where i have the logout button :
the content of header.component.ts ;
import { Router } from '#angular/router';
import { Component, OnInit } from '#angular/core';
import { HeaderService } from './header.service';
#Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {
constructor(public authService: HeaderService,public router:Router) { }
onLogout(){
this.authService.logout();
this.router.navigateByUrl('/');
}
the authService in above code is imported from header.service.ts and the header.service.ts goes like;
import { LoginService } from './../../login/login.service';
import { Injectable } from '#angular/core';
import {HttpClient} from '#angular/common/http'
import { Router } from '#angular/router';
interface LoginResponse {
success: boolean
}
export class HeaderService{
constructor(private router: Router,private http: HttpClient,private user:LoginService) {}
logout() {
this.http.delete<LoginResponse>('url-of-comapy');
this.router.navigate(['/']);
}
Basically i am trying to delete the authentication creds which i am getting from the url-of-company and is redirecting it to the login page
please help me with what is wrong an where i should do the correction and what to do for logout in my scenario .
I think what you need to do is delete the creds from localStorage not from the database which is what you are trying to do in the code above in logout() function.
You do not need the logout() function in authService and change your onLogout() function in header.component.ts to this:
onLogout(){
localStorage.removeItem('auth');
this.router.navigateByUrl('/login');
}

I am getting multiple calls from angular to the Post API in Node

I am trying to write a file from the data from the database but I'm getting multiple calls from the angular causing multiple entries of the same data.How can I stop that? And also it is causing to override write file after some time.
I am not getting what exactly should I do. I have tried subscribing thing in service in angular but it was of no help.
component.ts
import { Component, OnInit, ViewEncapsulation } from '#angular/core';
import { FormGroup, FormBuilder, Validators } from '#angular/forms';
import { NgbModalRef, NgbModal } from '#ng-bootstrap/ng-bootstrap';
import { ToastrService } from 'ngx-toastr';
import { CountryService } from './country.service';
import { ConfigService } from '../config.service';
#Component({
selector: 'app-country',
templateUrl: './country.component.html',
styleUrls: ['./country.component.scss'],
encapsulation: ViewEncapsulation.None,
providers: []
})
export class CountryComponent implements OnInit {
public modalRef: NgbModalRef;
public form: FormGroup;
public selectedCountry;
public countries;
constructor(public fb: FormBuilder, public toastrService: ToastrService,
public modalService: NgbModal, public configService: ConfigService,
public countryService: CountryService) {
}
ngOnInit() {
this.form = this.fb.group({
country: [null, Validators.compose([Validators.required])],
});
this.getCountries();
}
public getCountries() {
this.countryService.getCountries((data) => {
this.countries = data.countries;
}, (err) => { });
}
public selectCountry(country) {
this.countryService.selectCountry(country, (resp) => {
}, (err) => { });
}
}
service.ts
import { Injectable } from '#angular/core';
import { HttpClient, HttpHeaders, HttpParams } from '#angular/common/http';
import { ConfigService } from '../config.service';
import { ToastrService } from 'ngx-toastr';
#Injectable({
providedIn: 'root'
})
export class CountryService {
private setHeaders() {
const headers = new HttpHeaders({
'content-type': 'application/json',
});
return headers;
}
constructor(private configService: ConfigService, public http: HttpClient, public toastrService: ToastrService) { }
selectCountry(country: any, callback, errCallback) {
const options = {
headers: this.setHeaders(),
};
this.http.post(this.configService.url + '/selectedCountry', country, options).subscribe((resp: any) => {
callback(resp);
}, err => {
errCallback(err);
});
}
getCountries(callback, errCallback) {
const options = {
headers: this.setHeaders(),
};
this.http.get(this.configService.url + '/countries', options).subscribe((resp: any) => {
callback(resp.msg);
}, err => {
errCallback(err);
});
}
}
I want the call to be sent only once, not twice
Btw. - Please consider adding the NGRX lib in your app.
An angular-service is considered as a data holder. So make there an instance variable.
It could look like:
export class Service{
private countries;
...
public getCountries(){
return this.countries;
}
public loadCountries(){
this.http.get("url").subscribe(countries => this.countries = countries);
}
}
Then in your component class, you just get the countries.
export class Component{
public coutries;
...
public ngOnInit(){
this.countryService.getCountries(countries => this.countries=coutries);
}
}
And last but not least - load the countries in your AppComponent.
export class AppComponent{
...
public ngOnInit(){
this.countryService.loadCountries();
}
}
Need all your code if you can do a stackblitz, and like Mateusz said its better to handle state with ngrx if you dont want to call twice to backend or a simple approach its something like this https://stackblitz.com/edit/angular-biv6cw.
Change your service method like:
add interface:
export interface Country{
id: number;
name: string;
}
Change your method:
getCountries(): Observable<Country> {
return this.httpClient
.get('pass api url here')
.pipe(
map((body: any) => body),
catchError(error => of(error))
);
}
In your component:
ngOnInit() {
this.countryService.getCountries().subscribe(
(result: Countries) => {
this.countries = result;
},
err => {
log.debug('get countries error', err);
}
);
}
}
Try this:
// Somewhere on init
let postRequestCount = 0;
// More stuff …
// Just before doing the POST request inside the `selectCountry` method
if(postRequestCount < 1) {
http.post(); // TODO : Replace with the actual `post` method
}
postRequestCount++;

REST call works with axios but not with HttpClient in an Angular 5 project

Service.ts code
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Injectable({
providedIn: 'root'
})
export class ClientService {
constructor(private http: HttpClient) { }
getClients() {
return this.http.get<any>('http://localhost:8080/admin-api/client?count=15&page=0&q=', { withCredentials: true })
}
}
Component.ts code
import { Component, OnInit } from '#angular/core';
import { LazyLoadEvent } from 'primeng/api'
import { ClientService } from '../../services/client.service';
#Component({
selector: 'app-client',
templateUrl: './client.component.html',
styleUrls: ['./client.component.css']
})
export class ClientComponent implements OnInit {
constructor(private clientService: ClientService) { }
ngOnInit() {
this.loading = true
this.clientService.getClients().subscribe(data => {
console.log(data)
}, error => {
console.log(error)
})
}
}
The error I get when I run this
I don't understand why the same request can succeed using axios but not with the HttpClient in Angular.
Apparently, Axios adds the "X-XSRF-TOKEN" header when it detects the "XSRF-TOKEN" cookie whereas the HttpClient in Angular doesn't.
So you have to read the value of the "XSRF-TOKEN" cookie and set it as the header "X-XSRF-TOKEN" when sending your requests.

Angular 6 not getting response from expressjs node server

help a noob out, I am building a MEAN stack app and i ran into a problem where I cannot read a response from the express server but the response is generated when I use postman, here is my code
auth.service.ts
import { Injectable } from '#angular/core';
import { Http, Headers } from '#angular/http';
import { map } from 'rxjs/operators';
#Injectable({
providedIn: 'root'
})
export class AuthService {
authToken: any;
user: any;
constructor(private http:Http) { }
registerUser(user){
let headers = new Headers();
headers.append('Content-Type','application/json');
return this.http.post('http://localhost:3000/users/register',user,
{headers: headers})
.pipe(map(res => res.json));
}
authenticateUser(user){
let headers = new Headers();
headers.append('Content-Type','application/json');
return this.http.post('http://localhost:3000/users/authenticate',user,
{headers: headers})
.pipe(map(res => res.json));
}
}
login.component.ts
import { Component, OnInit } from '#angular/core';
import { AuthService } from '../../services/auth.service';
import { Router } from '#angular/router';
import { FlashMessagesService } from 'angular2-flash-messages';
#Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
username: String;
password: String;
constructor(private authService: AuthService,
private router: Router,
private flashMessage: FlashMessagesService
) { }
ngOnInit() {
}
onLoginSubmit(){
const user = {
username: this.username,
password: this.password
}
this.authService.authenticateUser(user).subscribe(data => {
console.log(data);
});
}
}
Chrome Console
ƒ () { login.component.ts:29
if (typeof this._body === 'string') {
return JSON.parse(this._body);
}
if (this._body instanceof ArrayBuffer) {
return JSON.parse(this.text());
Below is the response in Postman :
The error is in your pipe function.
pipe(map( res => res.json ))
You need to call res.json() inside your map. Convert it to
pipe(map( res => res.json() ))
However, converting the response to JSON is not required over Angular v5.
Correct code is as below:-
authenticateUser(user){
let headers = new Headers();
headers.append('Content-Type','application/json');
return this.http.post('http://localhost:3000/users/authenticate',user,
{headers: headers})
.pipe(map(res => res.json()));
}
Looks like data coming from authenticateUser is a function. Have you tried calling it?

Resources