I want to fetch the user value from the firebase.service.ts in my component file.
What is the way to return the user so that they are accessible in my stats.component.ts file? How to return the value inside a then block in service so that myData variable in component.ts has the updated user value from the service.
firebase.service.ts
import { Injectable } from "#angular/core";
import { Observable as RxObservable } from "rxjs/Observable";
import { HttpClient, HttpHeaders, HttpResponse } from "#angular/common/http";
import "rxjs/add/operator/map";
import "rxjs/add/operator/do";
import * as firebase from "nativescript-plugin-firebase";
#Injectable()
export class DataService {
user= [];
constructor() { }
firebaseInit() {
firebase.init({
}).then(
() => {
// console.log("initialized");
firebase.getValue('/companies')
.then(result => {
// JSON.stringify(result) will return the json object
// result.value will get the value
console.log(JSON.stringify(result.value));
this.user = result.value;
})
.catch(error => console.log("Error:" + error));
}
).catch(
(err) => {console.log("Error is: " + err)}
)
}
sendData() {
console.log( "Outside firebaseInit" + this.user);
}
}
stats.component.ts
import { Component, OnInit,Inject } from '#angular/core';
import {DataService} from "../services/firebase.service";
#Component({
moduleId:module.id,
templateUrl: "./stats.component.html"
})
export class StatsComponent {
private mydata;
constructor(private dataService:DataService){
}
ngOnInit(){
this.mydata = this.dataService.firebaseInit();;
}
}
You can try this method in your service. You should return data in your method
service
firebaseInit() {
return firebase.init({
}).then(
() => {
// console.log("initialized");
return firebase.getValue('/companies')
.then(result => {
// JSON.stringify(result) will return the json object
// result.value will get the value
console.log(JSON.stringify(result.value));
this.user = result.value;
return this.user;
})
.catch(error => console.log("Error:" + error));
}
).catch(
(err) => {console.log("Error is: " + err)}
)
}
In your component
ngOnInit(){
this.dataService.firebaseInit().then(data => this.mydata = data);
}
You have to return every function and result inside .then function, any missing return will break the promise chain.
You can directly return result without assigning to another variable.
firebaseInit() {
return firebase.init({
}).then(
() => {
// console.log("initialized");
return firebase.getValue('/companies')
.then(result => {
// JSON.stringify(result) will return the json object
// result.value will get the value
console.log(JSON.stringify(result.value));
return result.value;
})
.catch(error => console.log("Error:" + error));
}
).catch(
(err) => {console.log("Error is: " + err)}
)
}
Related
I would like to take a reponse from post metho and use this value in subscribe method.
In comments I wrote also information about my question.
My code
login(): void {
this.authService.login(this.model)
.subscribe(next => {
//here I wanted to use received value
this.alertifyService.success('success');
}, error => {
this.alertifyService.error('error');
}
);
}
and
login(model: any) {
return this.http.post(this.baseUrl + 'login', model)
.pipe(map((response: any) => {
// how to send this reponse to my subscribe method ?
const user = response;
if (user) {
localStorage.setItem('token', user.token);
this.decodedToken = this.jwtHelper.decodeToken(user.token);
console.log(this.decodedToken);
}
}
));
}
you just have to return the value from map
login(model: any) {
return this.http.post(this.baseUrl + 'login', model)
.pipe(map((response: any) => {
const user = response;
if (user) {
localStorage.setItem('token', user.token);
this.decodedToken = this.jwtHelper.decodeToken(user.token);
return this.decodedToken;
}
}
));
}
and then use it like this:
authService.login(/**/).subscribe(token => /*do something with the token*/)
I want to send this.data as a parameter for the post request but when I put a console.log(this.data) before the return statement, it returns both token and regNo are null values but inside the then method of storage get, console.log(this.data) gives the correct value. What is going wrong here?
import { Injectable } from "#angular/core";
import { Http } from '#angular/http';
import { Storage } from '#ionic/storage';
import 'rxjs/add/operator/toPromise';
import { DiaryModel } from './diary.model';
#Injectable()
export class DiaryService {
constructor(public http: Http, public storage: Storage) {}
data: any = {token: null, regNo: null};
getData(): Promise<DiaryModel> {
this.storage.get('regNo').then((val) => {
console.log(val);
this.data.regNo = val;
this.storage.get('user').then((val2) => {
console.log(val2);
this.data.token = val2.token;
});
});
return this.http.post("http://www.mysite.xyz/services/service.php", this.data)
.toPromise()
.then(response => response.json() as DiaryModel)
.catch(this.handleError);
}
private handleError(error: any): Promise<any> {
console.error('An error occurred', error); // for demo purposes only
return Promise.reject(error.message || error);
}
}
Ionic works as a non blocking I/O model. In your code return statement will run before getting the value from storage methods. You have to make the storage methods and return statement synchronous so return statement wait until the storage method resolves the value.
getData(): Promise<DiaryModel> {
return new Promise((resolve) =>{
data: any = {token: null, regNo: null};
this.storage.get('regNo').then((val) => {
console.log(val);
this.data.regNo = val;
this.storage.get('user').then((val2) => {
console.log(val2);
this.data.token = val2.token;
});
});
resolve(data);
});
}
returnData(): Promise<any> {
this.Data().then(res => {
return this.http.post("http://www.mysite.xyz/services/service.php", this.data)
.toPromise()
.then(response => response.json() as DiaryModel)
.catch(this.handleError);
}
}
Then you can call the returnData() method to get the return statement.
You need to chain the promises to get data sequentially. Since they are asynchronous.
Your http request is being sent before storage returns value.
I would do :
getData(): Promise<DiaryModel> {
let regPromise = this.storage.get('regNo');
let tokenPromise = this.storage.get('user');
return Promise.all([regPromise,tokenPromise]).then(values=>{
this.data.regNo=values[0];
this.data.token = values[1].token;
return this.http.post("http://www.mysite.xyz/services/service.php", this.data)
.toPromise()
.then(response => response.json() as DiaryModel)
.catch(this.handleError);
})
my current function looks like this:
import axios from 'axios';
export const GET_LOCATIONS = 'GET_LOCATIONS';
export function fetchLocals() {
const request = axios.get('http://localhost:3001/api')
.then(function(response) {
console.log(response.data)
})
.catch(function (error) {
console.log(error);
});
return {
type: GET_LOCATIONS,
payload: request
};
}
I want to be able to get the response.data outside of this so I can access its information and publish them!
Just return response.data from the .then handle, and it will be fine:
export function fetchLocals() {
const request = axios.get('http://localhost:3001/api')
.then(function(response) {
console.log(response.data);
return response.data;
})
.catch(function (error) {
console.log(error);
return Promise.reject(error);
});
return {
type: GET_LOCATIONS,
payload: request
};
}
Now you can call the function like this:
fetchLocals().payload
.then(data => {
// `data` will be `response.data` here
});
Note that a Promise.reject call is required in the catch handle to make the subsequent handlers identify a rejected promise.
I am creating an ionic login module, where in there are 2 observables , 1 inside another, Not sure if this is the correct way of implementation,
Here I am trying to call getHTTP() method, get a string, if the string is not empty then set it in ionic-storage varaible and then verify before logging in
Since Observables are async - getHTTP() is getting completed after the flow of login(credentials) , Help me out
import { Injectable } from '#angular/core';
import { Http } from '#angular/http';
import 'rxjs/add/operator/map';
import {Observable} from 'rxjs/Observable';
import {Headers} from '#angular/http';
import { Response } from '#angular/http';
import { Storage } from '#ionic/storage';
export class User {
name: string;
password: string;
url: string;
constructor(name: string, password: string, url: string) {
this.name = name;
this.password = password;
this.url = url;
}
}
/*
Generated class for the AuthService provider.
See https://angular.io/docs/ts/latest/guide/dependency-injection.html
for more info on providers and Angular 2 DI.
*/
#Injectable()
export class AuthService {
currentUser: User;
data = '';
constructor(public http: Http,private storage: Storage) {
console.log('Hello AuthService Provider');
}
// Make a call to Get CSRF and check if we have access
public getHTTP(credentials) {
let responseCSRF ;
const headers: Headers = new Headers();
headers.append('Authorization', 'Basic ' + btoa(credentials.user + ':' + credentials.password));
headers.append('Content-Type', 'application/json');
console.log(headers);
console.log('Clearing cache');
this.storage.set('CSRF', '');
this.storage.set('Auth',btoa(credentials.user + ':' + credentials.password));
this.storage.set('url', credentials.url);
//return
responseCSRF = this.http.get('http://' + credentials.url +'/Windchill/servlet/rest/security/csrf', {
headers: headers
}).map((response: Response) => response.json());
//console.log(typeof(responseCSRF))
responseCSRF.subscribe(x => {
console.log('CSRF ->' + x.items[0].attributes.nonce)
this.data = x.items[0].attributes.nonce;
if(typeof this.data!='undefined' && this.data) {
this.storage.set('CSRF', this.data);
}
});
return responseCSRF;
}
public login(credentials) {
if (credentials.user === null || credentials.password === null || credentials.url === null ) {
return Observable.throw("Please insert credentials ");
} else {
return Observable.create(observer => {
// At this point make a request to your backend to make a real check!
let access = false;
this.getHTTP(credentials).subscribe (
(resBody) => console.log('Boby is '+resBody),
error => console.error('Error from auth-service: ' + error))
, () => console.log('Completed!' + 'Auth' );
this.storage.get('CSRF').then((val) => {
console.log('Your CSRF is'+ val);
if(val!='undefined') {
access = true;
}
});
observer.next(access);
observer.complete();
});
}
}
public getUserInfo() : User {
return this.currentUser;
}
public logout() {
return Observable.create(observer => {
this.currentUser = null;
observer.next(true);
observer.complete();
});
}
}
In the Console
Headers {_headers: Map(2), _normalizedNames: Map(2)}
auth-service.ts:49 Clearing cache
auth-service.ts:57 pluck -->[object Object]
auth-service.ts:83 Your CSRF is
auth-service.ts:59 CSRF ->RkPYp+UtGGMRB+8NJHCr9rJ6WhBHdIVCfim585xXKgZ1TKUmf3v39tBqVRkjSb93dgWi4oF3KF4rNts0c3frktUdIFokNNVrMSGM47V3KwQhP8A5ARKr5rBsaxtmOtI=
auth-service.ts:78 Boby is [object Object]
Try to put your storage.get logic inside subscription handler:
return Observable.create(observer => {
// At this point make a request to your backend to make a real check!
let access = false;
this.getHTTP(credentials).subscribe(
(resBody) => {
console.log('Boby is ' + resBody);
this.storage.get('CSRF').then((val) => {
console.log('Your CSRF is' + val);
if (val != 'undefined') {
access = true;
}
observer.next(access);
observer.complete();
});
},
error => console.error('Error from auth-service: ' + error),
() => console.log('Completed!' + 'Auth'));
});
I have a trouble with angular 2 here.
I use service that return promise but when i try to retrive the response i got an error.
i was read this this stact question
this my code.
this is HotelService.ts
import { Injectable } from '#angular/core';
import { Http } from '#angular/http';
//rxjs promises cause angular http return observable natively.
import 'rxjs/add/operator/toPromise';
#Injectable()
export class HotelService {
private BASEURL : any = 'http://localhost:8080/hotel/';
constructor(private http: Http) {}
load(): Promise<any> {
return this.http.get(this.BASEURL + 'api/client/hotel/load')
.toPromise()
.then(response => {
response.json();
//console.log(response.json());
})
.catch(err => err);
}
}
this Hotel.ts (component)
import { Component, OnInit } from '#angular/core';
import { NavController } from 'ionic-angular';
import { HotelService } from '../../providers/hotel/hotelservice';
import { AboutPage } from '../../pages/about/about';
import { HotelDetailPage } from '../../pages/hoteldetail/hotel';
#Component({
selector: 'page-home',
templateUrl: 'home.html',
providers: [HotelService]
})
export class HomePage implements OnInit {
public searchBoxActive = false;
public hotels: any;
constructor(
private navCtrl: NavController,
private hotelServ: HotelService
) { }
load() {
this.hotelServ.load()
.then(res => {
this.hotels = res;
console.log(res); //why the rest is undefined?
console.log('ini component');
},
err => err);
}
toggleSearchBox() {
if (this.searchBoxActive == false) {
this.searchBoxActive = true;
} else {
this.searchBoxActive = false;
}
}
showAbout() {
this.navCtrl.setRoot(AboutPage);
}
pushDetail(evt, id) {
this.navCtrl.push(HotelDetailPage)
}
ngOnInit(): void {
this.load();
}
}
I have no idea.
You need to return response.json() from promise then callback:
load(): Promise<any> {
return this.http.get(this.BASEURL + 'api/client/hotel/load')
.toPromise()
.then(response => {
return response.json();
})
.catch(err => err);
}
The dfsq's answer is correct, but for the completeness' sake, below is an example according to the official Angular.io recommendations:
load(): Promise<any> {
return this.http.get(this.BASEURL + 'api/client/hotel/load')
.toPromise()
.then(response: Response) => response.json() || {})
.catch((error: Response | any) =>
{
let errMsg: string;
if (error instanceof Response)
{
const body = error.json() || '';
const err = body.error || JSON.stringify(body);
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
}
else
errMsg = error.message ? error.message : error.toString();
return Promise.reject(errMsg);
});
}
Key differences:
handle empty response in the then;
pretty up the error before throwing it further.