Angular 6 : Issue of component data binding - javascript

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));
}
}

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.

res.json() does not exist [duplicate]

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);

Cannot access variable outside the subscription

I have an component in angular. I get data from the API and I instantiate a new object to create a map. But I can't access a variable outside the subscribe function. I also can't access my method.
maps.service.ts
This part, get data form api
import { Injectable } from '#angular/core';
import {HttpClient} from '#angular/common/http';
#Injectable()
export class MapsService {
constructor(private http: HttpClient) { }
getMap(params) {
console.log('Service', params);
return this.http.get('/api/posts/' + params.id);
}
}
map.component.ts
Here, where I build the map with google in the future
import { Component, OnInit } from '#angular/core';
import {MapsService} from '../maps.service';
import {ActivatedRoute} from '#angular/router';
import {MapPath} from '../map-path';
#Component({
selector: 'app-maps',
templateUrl: './maps.component.html',
styleUrls: ['./maps.component.css']
})
export class MapsComponent implements OnInit {
results: any;
params: {};
test: any;
constructor(
private mapsService: MapsService,
private route: ActivatedRoute,
) { }
ngOnInit() {
this.route.params.subscribe( params => {
this.params = params;
});
this.mapsService.getMap(this.params).subscribe(
data => {
this.results = data;
this.test = new MapPath(data, 'test');
},
err => {
console.log('Error occured', err);
});
console.log('this.test', this.test.getX());
console.log('this.results', this.results);
}
}
map-path.ts
Here get the different properties from geoJSON
export class MapPath {
test: string;
constructor(path: any, test: string) {
this.test = test;
console.log('Path', path);
console.log('test', test);
}
getX() {
return this.test;
}
}
Thanks.
Your problem is that Observables are async functions, meaning your subscription callback will happen later than the console.log calls following your this.mapsService.getMap call.
This is guaranteed by async nature of Observables.
You can either move your console logs inside of the subscribe function or create another subscription.
Hope this helps.

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.

Categories

Resources