I am calling a api in my app component after getting the response I can decide which div is to show and which div is to hide.
But it render the html before completion of component process.
Below are the code example.
user.service.ts
import { Injectable } from '#angular/core';
import {Http,Headers, RequestOptions, Response, URLSearchParams} from '#angular/http';
#Injectable()
export class UserService {
private static isUserLoggedIn: boolean = false;
private userData: any;
constructor(private http: Http) { }
public isLoggedIn() {
return UserService.isUserLoggedIn;
}
public getUserData() {
return this.userData;
}
setUserData() {
var url = 'http://api.example.in/user/logincheck';
this.http
.get(url)
.map(response => response.json())
.subscribe(
(data) => {
this.userData = data;
if (typeof this.userData.id != 'undefined' && this.userData.id > 0) {
UserService.isUserLoggedIn = true;
}
},
(err) => { throw err; }
);
}
}
app.component.ts
import { Component, OnInit } from '#angular/core';
import { UserService } from './services/user/user.service';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [UserService],
})
export class AppComponent {
constructor(private userService: UserService) {
this.userLoggedInCheck();
}
ngOnInit() {
}
userLoggedInCheck() {
this.userService.setUserData();
}
}
I want here to load html after complete of userLoggedInCheck function called.
return a true value from userLoggedInCheck if the necessary conditions are met and assign it to a variable in the app.component.ts file. In the html file place the content within an *ngIf based on the return variable from the function.
for eg.
userLoggedInCheck() {
this.showHtml = this.userService.setUserData();
}
and in html
<div *ngIf="showHtml">
....... // code
</div>
Related
I am trying to build infinite scroll for my cards.
I am using a variable reload in data.service to check for need to load more data which is getting set to true when page end is getting reached.
The variable setting to true is done by app.component
The content population is done in post.component
And ```reload`` is present in data.service which is using http service to fetch for content from php server.
Curently I am using observable and trying to access reload status repeatedly but it is getting subscribed only once on Init.
app.component.ts
import { Component,HostListener } from '#angular/core';
import * as M from 'materialize-css';
import {DataService} from './current/posts/post-card/data.service';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent
{
title = 'cosmos';
constructor(private scrollSet: DataService){}
#HostListener('scroll', ['$event'])
onScroll(event:any)
{
if (event.target.offsetHeight + event.target.scrollTop >= event.target.scrollHeight-100)
{
console.log("noww");
this.scrollSet.setValue(true);
}
}
}
post.component.ts
import { Component, OnInit} from '#angular/core';
import {DataService} from './data.service';
import { DomSanitizer } from '#angular/platform-browser';
import {Title} from "#angular/platform-browser";
#Component({
selector: 'app-post-card',
templateUrl: './post-card.component.html',
styleUrls: ['./post-card.component.css']
})
export class PostCardComponent implements OnInit {
constructor(private data: DataService,public sanitizer: DomSanitizer,private titleService:Title)
{
this.titleService.setTitle("Current Feed | Cosmos");
}
received = 'none';
posts: any = [];
ngOnInit()
{
this.data.getPostData().subscribe(data =>
{
this.posts.push(data);
this.received='success';
},
error =>
{
this.received='error';
});
this.data.getValue().subscribe((value) => {
this.data.getPostData().subscribe(data =>
{
this.posts.push(data);
this.received='success';
},
error =>
{
this.received='error';
});
});
}
}
data.service.ts
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import {BehaviorSubject, Observable} from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class DataService {
private reload: BehaviorSubject<boolean>;
constructor(private http: HttpClient)
{
this.reload = new BehaviorSubject<boolean>(false);
}
fetchGap=5; // use this to set number of results wanted per fetch
fetchEnd:number= 0;
setValue(newValue): void {
this.reload.next(newValue);
}
getValue(): Observable<boolean> {
return this.reload.asObservable();
}
getPostData(){
this.fetchEnd+=this.fetchGap;
return this.http.get('http://localhost:1234/Server/getPosts.php?fetchEnd='+this.fetchEnd+'&fetchGap='+this.fetchGap);
}
}
the problem is that you haven't set the value of reload to false after your treatment.
try to check inside post.component.ts. here is a portion of that code, the block which suscribe to reload.
post.component.ts reload block
this.data.getValue().subscribe((value) => {
if(value){
this.data.getPostData().subscribe(data =>
{
this.posts.push(data);
this.received='success';
},
error =>
{
this.received='error';
});
this.data.setValue(false);
}
});
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));
}
}
Coming from the Angular1x background.I am migrating my existing app to Angular4
This is how my ng4 Service looks like
import { Injectable } from '#angular/core';
import {Http} from '#angular/http';
#Injectable()
export class DataService {
private _http : Http;
constructor(http:Http) {
this._http = http;
}
public GetPosts() : any{
this._http.get("https://jsonplaceholder.typicode.com/posts").subscribe(data => {
const posts = data.json();
console.log(posts); // logs the desired json
return posts;
})}}
Consuming the above service from the component.
import { Component, OnInit } from '#angular/core';
import {Customer} from './customer.model';
import {DataService } from '../../providers/data.service';
#Component({
selector: 'app-customer',
templateUrl: './customer.component.html',
styleUrls: ['./customer.component.css']
})
export class CustomerComponent implements OnInit {
private _dService: DataService;
constructor(dService:DataService) {
this._dService = dService;}
ngOnInit() {}
public GetAll(){
let posts =this._dService.GetPosts();
debugger;
console.log(posts); // undefined
/* here the posts is getting UNDEFINED (error) */
}}
In Angular1X, I used to return promise from ngService but how do the same in angular4??
You should subscribe to the observable in the component, not in the service.
In your service
public GetPosts() : any{
return this._http.get("https://jsonplaceholder.typicode.com/posts");
}
And in your component
this._dService.GetPosts().subscribe(data => {
const posts = data.json();
console.log(posts);
// Do whatever you like with posts
)};
The call to subscribe should be in the component's code
constructor(private http:Http) { }
getPosts(){
return this.http.get('https://jsonplaceholder.typicode.com/posts').map(
(response: Response) => {
return response.json();
}
)
}
And in the component:
the best practice you declare :
data : any;
this._dService.GetPosts().subscribe(
data => {this.data = data;
console.log(this.books);},
err => {console.log(err);},
()=> {console.log("terminated");}
);
My http-data.service accepts json for output in the component template. Initially, the console shows that the first few calls are given undefined, and the following calls are already taking json, but also if you check the component, then the component shows that the method that outputs the data to the component is called only once and since the data has not yet arrived it writes undefined , But not updated after the arrival of json. Help please understand why? Thank you
My http-data.service:
import {Injectable} from '#angular/core';
import {Http} from '#angular/http';
import {Response} from '#angular/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
#Injectable()
export class HttpService{
constructor(private http: Http) {}
getDataOrganizations(): Observable<any[]>{
return this.http.get('http://localhost:3010/data')
.map((resp:Response)=>{
let dataOrganizations = resp.json().organization;
return dataOrganizations;
});
}
getDataModules(): Observable<any[]> {
return this.http.get('http://localhost:3010/data')
.map((resp: Response)=> {
let dataModules = resp.json().modules;
return dataModules;
});
}
getDataPresets(): Observable<any[]> {
return this.http.get('http://localhost:3010/data')
.map((resp: Response)=> {
let dataPresets = resp.json().presets;
return dataPresets;
});
}
getDataModuleItems(): Observable<any[]> {
return this.http.get('http://localhost:3010/data')
.map((resp: Response)=> {
let dataModuleItems = resp.json().module_items;
return dataModuleItems;
});
}
}
My data-all.service
import { Injectable, EventEmitter } from '#angular/core';
import {Response} from '#angular/http';
import { ModuleModel } from './model-module';
import { ModuleItemsModel } from './model-module-items';
import data from '../data/data-all';
import { PriceService } from './price.service';
import { HttpService } from './http-data.service';
#Injectable()
export class ModuleDataService {
constructor(private priceService: PriceService, private httpService: HttpService){
this.dataMinMaxSum = {minSum: 0, maxSum: 0}
}
private currentPopupView: EventEmitter<any> = new EventEmitter<any>();
private dataModules: ModuleModel[] = this.getDataModules();
private dataMinMaxSum: {};
private dataCalculateVariationOrg: any[];
private dataChangeExecutor: any[];
subscribe(generatorOrNext?: any, error?: any, complete?: any) {
this.currentPopupView.subscribe(generatorOrNext, error, complete);
}
calculte(){
return this.priceService.getDataPrice();
}
getDataModules(){
this.httpService.getDataModules().subscribe(((modules)=>{this.dataModules = modules; console.log(this.dataModules);}));
console.log('dataModules');
console.log(this.dataModules);
return this.dataModules;
}
---------------------------------------------------------------------------
}
My left-block.component
import { Component, OnInit} from '#angular/core';
import { ModuleDataService } from '../../service/data-all.service';
import { ModuleModel } from '../../service/model-module';
#Component({
moduleId: module.id,
selector: 'modules-left-block',
templateUrl: './modules-left-block.html',
styleUrls: ['modules-left-block.css']
})
export class ModuleLeft implements OnInit{
modules: ModuleModel[];
constructor(private modulesAll: ModuleDataService){}
ngOnInit(){
this.modules = this.modulesAll.getDataModules();
console.log("view");
console.log(this.modulesAll.getDataModules());
}
onToggle(module: any){
this.modulesAll.toggleModules(module);
}
}
My left-block.component.html
<div class="modules-all">
<div class="modules-all-title">Все модули</div>
<div class="module-item" *ngFor="let module of modules" [ngClass]="{ 'active': module.completed }" (click)="onToggle(module)">{{module?.title}}</div>
</div>
In the component this.modulesAll.getDataModules () method is why it is executed only once without updating (write in console => undefined), if there are any thoughts, write, thanks.
This behaviour is due to the .subscribe() method does not wait for the data to arrive and I'm guessing you already know this. The problem you're facing is because, you have .subscribe to the getDataModules() service in the wron place. You shouldn't subscribe to a service in another service (at leat in this case). Move the subscribe method to the left-block.component and it should work.
getDataModules() {
this.httpService.getDataModules().subscribe(((modules) => {
this.dataModules = modules;
console.log(this.dataModules);
}));
console.log('dataModules');
console.log(this.dataModules);
return this.dataModules;
}
It should look somethig like this:
#Component({
moduleId: module.id,
selector: 'modules-left-block',
templateUrl: './modules-left-block.html',
styleUrls: ['modules-left-block.css']
})
export class ModuleLeft implements OnInit {
modules: ModuleModel[] = new ModuleModel();
constructor(private modulesAll: ModuleDataService, private httpService: HttpService) {}
ngOnInit() {
this.getDataModles();
//this.modules = this.modulesAll.getDataModules();
console.log("view");
//console.log(this.modulesAll.getDataModules());
}
onToggle(module: any) {
this.modulesAll.toggleModules(module);
}
getDataModules(): void {
this.httpService.getDataModules().subscribe(((modules) => {
this.modules = modules;
console.log(this.dataModules);
}));
}
}
I want to share an object from my first component to the second. I am able to log the 'strVal'(string) defined in the Login Component, in my Home Component but I am unable to log the value of 'abc'(Object) from the Login Component, in the HomeComponent. I am confused why one value from Login Component gets available to Home Component and other does not! The code for Login Component in below
Login.Component.ts
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import { AuthenticationService } from '../_services/index';
import { User } from '../contract';
#Component({
moduleId: module.id,
templateUrl: 'login.component.html'
})
export class LoginComponent implements OnInit {
model: any = {};
loading = false;
error = '';
us: User[];
abc: any[];
strVal: string = "Rehan";
current: any;
constructor(
private router: Router,
private authenticationService: AuthenticationService) { }
ngOnInit() {
// reset login status
this.authenticationService.logout();
this.getUs();
}
login() {
this.loading = true;
this.authenticationService.login(this.model.username, this.model.password)
.subscribe(result => {
if (result) {
this.router.navigate(['/']);
}
else {
alert('Username and Password Incorrect');
this.loading = false;
this.model = [];
this.router.navigate(['/login']);
}
});
}
getUs() {
this.authenticationService.getUsers().subscribe(
res => this.us = res
);
}
chek() {
this.abc = this.us.filter(a => a.Login === this.model.username);
console.log(this.abc);
}
}
Home.Component.ts
import { Component, OnInit, Input } from '#angular/core';
import { AuthenticationService } from '../_services/index';
import { LoginComponent } from '../login/index';
import { User } from '../contract';
#Component({
moduleId: module.id,
templateUrl: 'home.component.html',
providers: [LoginComponent]})
export class HomeComponent implements OnInit {
users: User[];
constructor(private userService: AuthenticationService, private Log: LoginComponent) { }
ngOnInit() {
this.userService.getUsers().subscribe(
res => this.users = res
);
console.log(this.Log.strVal);
console.log(this.Log.abc);
}
}
Any hint or help will be appreciated. Thanks!