res.json() does not exist [duplicate] - javascript

This question already has answers here:
res.json() is a not a function in HttpClient Angular 2
(2 answers)
Closed 4 years ago.
I am trying to create a simple post in a service class using Angular/Typescript
My IDE does not give me any error, but when I call the function, I am getting undefined. I am not sure where the problem is based. I did some research, and it seems like the problem might be with the HttpClient I am importing, but I can not find anything relevant.
Front-end Function:
import { Injectable } from '#angular/core';
import { HttpClient, HttpHeaders} from '#angular/common/http';
import { Response } from '#angular/http';
import 'rxjs/add/operator/map';
#Injectable()
export class ServiceClassAuth {
auth: any;
user: any;
constructor(private http: HttpClient) {}
signinUser(user) {}
login(user) {
let headers = new HttpHeaders();
headers.append('Content-Type', 'application/json');
const loginUrl = 'http://localhost:3000/login';
return this.http.post(loginUrl, user, {
headers: headers
}).map((res: Response) => res.json());
}
}
A component which calls the Service:
import { Component, OnInit } from '#angular/core';
import {
MatDialog,
MatDialogRef,
MAT_DIALOG_DATA
} from '#angular/material';
import { Inject } from '#angular/core';
import { ServiceClassAuth } from '../service/service-class-auth';
#Component({
selector: 'app-signin',
templateUrl: './signin.component.html',
styleUrls: ['./signin.component.css'],
providers: [ServiceClassAuth]
})
export class SigninComponent implements OnInit {
username: String;
password: String;
ngOnInit() {}
constructor(
public dialogRef: MatDialogRef < SigninComponent > ,
#Inject(MAT_DIALOG_DATA) public data: any,
private authService: ServiceClassAuth) {}
onNoClick(): void {
this.dialogRef.close();
}
loginSubmit(postValues): void {
const user = {
'usr': postValues.value.usrname,
'psw': postValues.value.psw
}
const res = this.authService.login(user).subscribe(res => {
if (res.success) {
} else {
//DO ALERT
}
});
}
}

With HttpClient (Angular 4.3+), you do not have to use res.json() , the response object is JSON by default, Just use response directly.
return this.http.post(loginUrl, user, {
headers: headers
}).map((res: Response) => res);

Related

Problem with displaying data from api in Angular 6

In my app I am calling the iTunes api and when I log the response it is coming back with [object object]. I know it must be to do with the array structure of the api. I have a service being injected into a component as follows: BTW I have a proxy.conf.json file for the api.
service.ts
import { Injectable } from '#angular/core';
import { HttpClient, HttpEventType, HttpHeaders, HttpRequest, HttpResponse, HttpErrorResponse } from '#angular/common/http';
import { Observable, of, throwError } from 'rxjs';
import { catchError, retry } from 'rxjs/operators';
#Injectable({
providedIn: 'root'
})
export class ApiService {
api: string = 'api';
constructor(
private http: HttpClient,
) { }
getAll(): Observable<any> {
return this.http.get<any>(this.api)
.pipe(
catchError(this.handleError)
);
}
private handleError(error: HttpErrorResponse) {
if (error.error instanceof ErrorEvent) {
console.log(error.error.message)
} else {
console.log(error.status)
}
return throwError(
console.log('Something is wrong!'));
};
}
component.ts
import { Component, OnInit } from '#angular/core';
import { HttpClient, HttpEventType, HttpHeaders, HttpRequest, HttpResponse } from '#angular/common/http';
import { ApiService } from '../../../services/api.service';
#Component({
selector: 'app-content',
templateUrl: './content.component.html',
styleUrls: ['./content.component.scss']
})
export class ContentComponent implements OnInit {
public results = [];
constructor(private service: ApiService) { }
private http: HttpClient
ngOnInit() {
this.getApi();
}
private getApi() {
this.service.getAll().subscribe((results) => {
console.log('JSON Response = ' + results);
})
}
}
Api structure
{
"resultCount":50,
"results":[
{
"wrapperType":"track",
"kind":"song",
"artistId":271256
},
]
}
Any ideas?
The format is correct, if you want to see it as a JSON, you need to use JSON.stringify
this.service.getAll().subscribe((results) => {
console.log('JSON Response = ' + JSON.stringify(results));
data = results.results;
})
if you want to iterate over elements with ngFor use
<li *ngFor="let dataObj of data">
{{ dataObj.wrapperType}}
</li>

ERROR TypeError: Cannot read property 'subscribeNewsletter' of undefined at newsletter.component.ts.NewsletterComponent.subscribeNewsletter

I'm getting this error : ERROR TypeError: Cannot read property 'subscribeNewsletter' of undefined at NewsletterComponent.subscribeNewsletter (newsletter.component.ts:47) when I try to create a service to subscribe to a newsletter from a form.
This is my NewsletterComponent :
import { Component, OnInit, Inject, forwardRef } from '#angular/core';
import { NewsletterService } from '../common/service/newsletter.service';
import { NewsletterDto } from '../common/model/dto/newsletter-dto';
import { FormGroup } from "#angular/forms";
import { FormControl } from '#angular/forms';
#Component({
selector: 'app-user-cmp',
templateUrl: 'newsletter.component.html'
})
export class NewsletterComponent implements OnInit {
newsletterService: NewsletterService;
newsletterForm: FormGroup;
newsletter: NewsletterDto;
ngOnInit() {
this.newsletterForm = new FormGroup({
'subscribe': new FormControl(null),
});
}
constructor() {}
subscribeNewsletter(): void {
this.newsletter = {
subscribe: this.newsletterForm.controls['subscribe'].value
};
this.newsletterService.subscribeNewsletter(this.newsletter).subscribe(newsletter => this.newsletter = newsletter);
}
}
And this is my NewsletterService :
import { Injectable } from '#angular/core';
import { Http, Response, Headers, RequestOptions } from '#angular/http';
import { NewsletterDto } from '../model/dto/newsletter-dto';
import { Observable, of } from 'rxjs';
import { map, catchError } from "rxjs/operators";
#Injectable({
providedIn: 'root'
})
export class NewsletterService {
private newsletterUrl = 'rest/newsletter/subscription';
constructor(private http: Http) { }
subscribeNewsletter(newsletter: NewsletterDto): Observable<any> {
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http
.post(this.newsletterUrl, newsletter, options).pipe(
map((res: any) => res.json()),
catchError(<T>(error: any, result?: T) => {
console.log(error);
return of(result as T);
})
);
}
}
I don't really get where's the problem ? Can anyone enlighten me a little bit ? Thanks !
In your component you declare
newsletterService: NewsletterService;
It's means newsletterService type is NewsletterService. But you are not creating any instance of NewsletterService class.
In your service subscribeNewsletter method can be accessible via object, So first you need to create new instance of your service.
You can do it on your component just like
constructor(private newsletterService: NewsletterService) { }
and remove other declaration which you already given.
This dependency injector automatically create instance if not present.
Other way you can do this but that's not good way.
newsletterService: NewsletterService=new NewsletterService();
You should inject the service in constructor
constructor(public newsletterService: NewsletterService) {
/* do the construction stuff */
}
Make sure to remove the other newsletterService property defined before costructor.

Angular 6 : Issue of component data binding

I call service which make http call, I assign response to component variable now when I try access that component variable to view it display blank.
Means component variable assign in subscribe successfully but cant acceess in html view.
I think view is loaded before values assign to component data.
component
import {Component, OnInit, ChangeDetectionStrategy} from '#angular/core';
import { UserService } from '../../../../../core/services/users/user.service';
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'm-user-list',
templateUrl: './user-list.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class UserListComponent implements OnInit {
list;
roles = {};
current_page: any
totalRecords: any
public showContent: boolean = false;
constructor(private userService: UserService, private http: HttpClient) {
}
ngOnInit() {
this.getRecords();
}
getRecords(){
this.getResultedPage(1);
}
getResultedPage(page){
return this.userService.getrecords()
.subscribe(response => {
this.list = response.data;
});
}
}
Service
import { Injectable } from '#angular/core';
import { Observable, of, throwError } from 'rxjs';
import { HttpClient, HttpParams , HttpErrorResponse, HttpHeaders } from '#angular/common/http';
import { map, catchError, tap, switchMap } from 'rxjs/operators';
const httpOptions = {
headers: new HttpHeaders({'Content-Type': 'application/json'})
};
import { UtilsService } from '../../services/utils.service';
import { AppConfig } from '../../../config/app'
#Injectable({
providedIn: 'root'
})
export class UserService{
public appConfig: AppConfig;
public API_URL;
constructor(private http: HttpClient, private util: UtilsService) {
this.appConfig = new AppConfig();
this.API_URL = this.appConfig.config.api_url;
}
private extractData(res: Response) {
let body = res;
return body || { };
}
private handleError(error: HttpErrorResponse) {
if (error.error instanceof ErrorEvent) {
// A client-side or network error occurred. Handle it accordingly.
console.error('An error occurred:', error.error.message);
} else {
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong,
console.error(
`Backend returned code ${error.status}, ` +
`body was: ${error.error}`);
}
// return an observable with a user-facing error message
return throwError('Something bad happened; please try again later.');
};
getrecords(): Observable<any> {
return this.http.get('/api/users', httpOptions).pipe(
map(this.extractData),
catchError(this.handleError));
}
}

Angular 5 component expecting an argument

Im trying a simple profile app, and all the sudden Im getting error TS2554
ERROR in /app/components/profile/profile.component.ts(25,3): error TS2554: Expected 1 arguments, but got 0.
import { Component, OnInit } from '#angular/core';
import { AuthService } from '../../services/auth.service';
import { FlashMessagesService } from 'angular2-flash-messages';
import { Router } from '#angular/router';
#Component({
selector: 'app-profile',
templateUrl: './profile.component.html',
styleUrls: ['./profile.component.css']
})
export class ProfileComponent implements OnInit {
user: Object;
constructor(
private auth: AuthService,
private flashMsg: FlashMessagesService,
private router: Router
) {
}
ngOnInit() {
this.auth.getProfile().subscribe( profile => {
this.user = profile.user;
},
err => {
return false;
});
}
}
auth.service.ts
import { Injectable } from '#angular/core';
import { Http, Headers } from '#angular/http';
import 'rxjs/add/operator/map';
import { tokenNotExpired } from 'angular2-jwt';
#Injectable()
export class AuthService {
authToken: any;
user: any;
constructor(
private http: Http
) {
}
getProfile(user) {
let headers = new Headers();
this.loadToken();
headers.append('Authorization', this.authToken);
headers.append('Content-Type','application/json');
return this.http.get('http://localhost:3000/users/profile', {headers:headers})
.map(res => res.json());
}
loadToken() {
const token = localStorage.getItem('id_token');
this.authToken = token;
}
}
Your getProfile is expecting an argument named user but you are not passing it from the component
You need to pass an argument as follows,
this.auth.getProfile(user).subscribe( profile => {
this.user = profile.user;
},
err => {
return false;
});
or if you don't need an argument , remove it from your service method.

Angular 2 Interface throwing error of non existing property

I have an Angular 2 interface books.ts
export interface Books {
artists: Object;
tracks: Object;
}
This is the my service file where I am using it with http request searchService.ts
import { Injectable } from '#angular/core';
import { Http, Response, Headers, RequestOptions } from '#angular/http';
import { Observable } from 'rxjs/Observable';
import { Books } from 'app/pages/search-results/books';
import 'rxjs/add/operator/map'
#Injectable()
export class SearchService {
constructor(private _http:Http) { }
getBook(keyword): Observable<Books[]>{
return this._http.get('https://api.spotify.com/v1/search?q=' + keyword + '&type=track,artist')
.map((response: Response) => <Books[]> response.json());
}
}
And this is my component where I am using interface searchResults.ts
import { Component, OnInit } from '#angular/core';
import { ActivatedRoute, Router } from '#angular/router';
import { SearchService } from 'app/shared/search/search.service';
import { Books } from 'app/pages/search-results/books';
#Component({
selector: 'app-search-results',
templateUrl: './search-results.component.html',
styleUrls: ['./search-results.component.css'],
providers: [SearchService]
})
export class SearchResultsComponent implements OnInit {
keyword: any;
sub: any;
books: Books[];
errMessage: string;
arists: Object;
constructor(private _route: ActivatedRoute, private _router: Router, private _search: SearchService) { }
ngOnInit() {
this.sub = this._route
.queryParams
.subscribe(params => {
// Defaults to 0 if no query param provided.
this.keyword = params['keyword'] || 0;
this.getBooks(this.keyword);
});
//
}
getBooks(value) {
this._search.getBook(value)
.subscribe(
res => {
this.books = res;
console.log(res.artists);
},
error => { this.errMessage = <any>error }
);
}
}
The error comes when I try to console the res.artists. The error says Property 'artists' does not exist on type 'Books[]'. I am new to Angular 2 and doesn't know how to fix that.
The response is looks like
{artists:{limit: 20, item:[]}, tracks:{limit: 20, item:[]}}
I'm not sure but I think you try to get res.artist from collection of books. You can check it by for or e.g res[0].artist to get concrete artist.
getBook function in class SearchService return an array of Books object (Books[])
so, the res in getBooks function in SearchResultsComponent will be an Array of Books.
You can console.log(res) to see detail, if you want access to artists please try with res[0].artists if the res is not an empty array
The problem is that I am getting Object in response and I am assigning it to an Array which is causing the error. I have simply changes the both types to object and it solved my problem.
From this
books: Books[];
To this
books: Books;

Categories

Resources