Ionic 2 HTTP request not working - Angular 2 - ionic-framework

Hi I'm trying to do a simple Http GET request, but can't get it to work in ionic v2 Beta...
here is my app.js:
import {App, Platform} from 'ionic-angular';
import {TabsPage} from './pages/tabs/tabs';
import {HTTP_BINDINGS} from 'angular2/http';
#App({
template: '<ion-nav [root]="rootPage"></ion-nav>',
providers: [HTTP_BINDINGS],
config: {} // http://ionicframework.com/docs/v2/api/config/Config/
})
export class MyApp {
static get parameters() {
return [[Platform]];
}
constructor(platform) {
this.rootPage = TabsPage;
platform.ready().then(() => {
});
}
}
and this is my page1.js:
import {Page} from 'ionic-angular';
import {Http} from 'angular2/http';
#Page({
templateUrl: 'build/pages/page1/page1.html'
})
export class Page1 {
constructor(http:Http) {
this.mget = http.get("https://httpbin.org/ip")
.subscribe(data => {
var alert = Alert.create({
title: "Your IP Address",
subTitle: data.json().origin,
buttons: ["close"]
});
this.nav.present(alert);
}, error => {
console.log(JSON.stringify(error.json()));
});
}
}
When adding http:Http to the constructor -> constructor(http:Http) the whole app goes blank in browser...
And I get an error in Console:
Error: Cannot find module "../page1/page1"
I've also tried this in Page1.js:
export class Page1 {
constructor() {
}
makeGetRequest() {
this.http.get("https://httpbin.org/ip")
.subscribe(data => {
var alert = Alert.create({
title: "Your IP Address",
subTitle: data.json().origin,
buttons: ["close"]
});
this.nav.present(alert);
}, error => {
console.log(JSON.stringify(error.json()));
console.log('yolo')
alert('hello');
});
}
}
and then call makeGetRequest() on (click) in page1.html
but it returns these exeptions:
EXCEPTION: Error during evaluation of "click"
ORIGINAL EXCEPTION: TypeError: this.http is undefined
please help!
:)
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
THIS IS THE SOLUTION:
page1.js:
import {Page} from 'ionic-angular';
import {Http} from 'angular2/http';
#Page({
templateUrl: 'build/pages/page1/page1.html'
})
export class Page1 {
static get parameters(){
return [Http];
}
constructor(http) {
this.http = http;
this.mget = this.http.get("https://httpbin.org/ip")
.subscribe(data => {
console.log(data);
}, error => {
console.log('faild');
});
}
}
app.js:
import {App, Platform} from 'ionic-angular';
import {TabsPage} from './pages/tabs/tabs';
import { HTTP_PROVIDERS } from 'angular2/http';
#App({
template: '<ion-nav [root]="rootPage"></ion-nav>',
providers: [HTTP_PROVIDERS],
config: {} // http://ionicframework.com/docs/v2/api/config/Config/
})
export class MyApp {
static get parameters() {
return [[Platform]];
}
constructor(platform) {
this.rootPage = TabsPage;
platform.ready().then(() => {
});
}
}

Please try this
export class Page1 {
static get parameters(){
return [Http];
}
constructor(http) {
this.http = http;
this.mget = this.http.get("https://httpbin.org/ip")
.subscribe(data => {
var alert = Alert.create({
title: "Your IP Address",
subTitle: data.json().origin,
buttons: ["close"]
});
this.nav.present(alert);
}, error => {
console.log(JSON.stringify(error.json()));
});
}
}
I would recommend you to write the get request inside a separate service and inject it in your page.
Also have a look at this - http://tphangout.com/?p=113
Detailed and simple instructions are given there for making a simple GET request from an Ionic 2 app.

I believe you need to
import { HTTP_PROVIDERS } from 'angular2/http';
in your app.js instead of HTTP_BINDINGS and change providers: [HTTP_BINDINGS] to providers: [HTTP_PROVIDERS]
See Angular2 docs

Related

ngrx jasmine-marbles test resulting the "Received" part returning '?' question mark

I am having an issue with the following tech-stack:
Angular v8,
ionic Angular v5,
ngrx v8,
jasmine-marbles v0.8.3.
I am writing a unit test for "ngrx", in particular the "effects" part.
Following is my code snippet:
import { TestBed } from '#angular/core/testing';
import { provideMockActions } from '#ngrx/effects/testing';
import { Observable } from 'rxjs';
import { InformationEffects } from './information.effects';
import { HttpClientTestingModule, HttpTestingController } from '#angular/common/http/testing';
import { Storage } from '#ionic/storage';
import { DataService } from 'src/app/shared/services/data.service';
import { RouterTestingModule } from '#angular/router/testing';
import { cold, hot } from 'jasmine-marbles';
import { MockStore, provideMockStore } from '#ngrx/store/testing';
import {
InformationRequested,
InformationSuccess,
} from './information.actions';
describe('Information Effects', () => {
let information = {} as any;
const initialState = { information: information};
let actions$: Observable<any>;
let effects: InformationEffects;
let store: MockStore<any>;
let dataService;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule, RouterTestingModule],
providers: [
{
provide: Storage,
},
InformationEffects,
MockStore,
provideMockStore({ initialState }),
provideMockActions(() => actions$),
{
provide: DataService,
useValue: jasmine.createSpyObj('DataService', ['getInformation'])
}
]
});
effects = TestBed.get(InformationEffects);
store = TestBed.get(MockStore);
dataService = TestBed.get(DataService);
});
it('should be created', () => {
expect(effects).toBeTruthy();
});
describe('INFORMATION_REQUESTED', () => {
it('should return an InformationSucess action, with the user, on success', () => {
let language = {} as any;
const action = new InformationRequested(language);
const outcome = new InformationSuccess(information);
actions$ = hot('-a-', { a: action });
const response = cold('-a|', { a: information });
const expected = cold('--b', { b: outcome });
dataService.getInformation.and.returnValue(response);
expect(effects.informationAction$).toBeObservable(expected);
});
});
});
When I run the test using "npm test", it failed at the "Received" part showing "?".
It says:
Expected: --b,
Received: --?,
Expected:
[{"frame":20,"notification":{"kind":"N","value":{"payload":{},"type":"[Information]
INFORMATION Success"},"hasValue":true}}]
Received:
[{"frame":20,"notification":{"kind":"N","value":{"payload":{},"type":"[Information]
INFORMATION Success"},"hasValue":true}}],
Please refer below figure:
enter image description here
I had searched the internet for this question mark in the "Received:" section, to no avail. I had also researched on each jasmine-marbles syntaxes, as well the (hot & cold) observable, to understand why & how to use it. Still no solution to get rid of the '?' question mark to have the unit-test being "Success". As such please help me.

Rest web service returns null value on mobile device but works on PC in Ionic App

i am consuming Rest JSONP Web Service in an ionic App which works fine on PC but returns null value on mobile devices
My page.ts file
import {
Component,
OnInit
} from '#angular/core';
import {
AlertController,
LoadingController
} from '#ionic/angular';
import {
ActionSheetController
} from '#ionic/angular';
import {
Router
} from '#angular/router'
import {
ProApiService
} from './../../../../services/pro-api.service';
#Component({
selector: 'app-ranked-diagnosis',
templateUrl: './ranked-diagnosis.page.html',
styleUrls: ['./ranked-diagnosis.page.scss'],
})
export class RankedDiagnosisPage implements OnInit {
tabSelect: string = 'show10';
show10Data: Array < any >= [];
showAllData: Array < any >= [];
redFlagsData: Array < any >= [];
loading: any;
constructor(
private api: ProApiService,
public alertController: AlertController,
public loadingController: LoadingController,
public actionSheetController: ActionSheetController,
private router: Router
) {}
segmentChanged(event: any) {
this.tabSelect = event.detail.value;
}
async presentActionSheet(buttons) {
const actionSheet = await this.actionSheetController.create({
header: 'Sub Diagnosis',
buttons: buttons
});
await actionSheet.present();
}
async presentAlert(msg: string, header: string) {
const alert = await this.alertController.create({
header: '',
subHeader: header,
message: msg,
buttons: ['OK']
});
await alert.present();
}
async presentLoading() {
this.loading = await this.loadingController.create({
message: 'loading...',
});
return await this.loading.present();
}
ngOnInit() {
}
ionViewWillEnter() {
if (this.api.ProApiData.diagnoses_checklist.diagnoses) {
this.showAllData =
this.api.ProApiData.diagnoses_checklist.diagnoses;
for (let i = 0; i < 10; i++) {
this.show10Data.push(this.showAllData[i]);
}
this.showAllData.forEach(item => {
if (item.red_flag == 'true') {
this.redFlagsData.push(item);
}
});
console.log(this.showAllData);
} else {
console.log('error');
this.router.navigateByUrl('isabel-pro');
}
}
why_diagnosis(url: any, weightage: any) {
this.presentLoading();
this.api.why_diagnosisApi(url).subscribe(res => {
let matched_terms = res._body.why_diagnosis.matched_terms;
console.log(matched_terms);
let alertMsg = `We matched the terms: ${matched_terms}<br><hr>Degree of match between query entered and database: ${weightage}`;
this.presentAlert(alertMsg, 'Why did this diagnosis come up ?');
this.loadingController.dismiss();
}, err => {
this.loadingController.dismiss();
console.log('error');
});
}
}
in the above code i am calling why_diagnosis function which calls the function from a service file.
My service.ts file
import {
Injectable
} from '#angular/core';
import {
HttpClient,
HttpHeaders
} from '#angular/common/http';
import {
Jsonp
} from '#angular/http';
import {
Observable
} from 'rxjs';
import {
map
} from 'rxjs/operators';
import {
ConstantsService
} from './../../../services/constants.service';
#Injectable({
providedIn: 'root'
})
export class ProApiService {
apiRoot = this.root.APIroot;
diagnosisPROData: any;
drugData: any;
ProApiData: any;
drugApiData: any;
constructor(
private jsonp: Jsonp,
private http: HttpClient,
private root: ConstantsService) {}
why_diagnosisApi(url: any): Observable < any > {
let whyUrl = `${this.apiRoot}Mob_isabelPRO.php?
why_url=${url}&callback=JSONP_CALLBACK`;
return this.jsonp.request(whyUrl, 'callback')
.pipe(
map(
res => {
let why_diagnosis = res;
return why_diagnosis;
}
)
);
}
}
above code is from my service file.
this is the value i am getting in PC
this is the return on mobile
i dont know whats wrong with it. please suggest me the solution
Thanks

passing parameter between pages ionic

Hi i´m new in ionic and I am trying to pass the scann information form one page to another, the thing its that when I execute the program I have a console.log to check if the info its passed correctly but on chrome console said undefined, letme paste my code:
home.ts where i try to send the info from the scan:
import { Component } from '#angular/core';
import { NavController,Platform } from 'ionic-angular';
import { BarcodeScanner } from '#ionic-native/barcode-scanner';
import { TabsPage } from '../tabs/tabs';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
private barcodeText:String;
private barcodeFormat:String;
private platform:Platform;
private navController:NavController;
constructor(private barcodeScanner: BarcodeScanner,public navCtrl: NavController,platform:Platform) {
this.platform = platform;
this.navController = navCtrl;
}
doScan(){
console.log('scannig product barcode');
this.platform.ready().then(() => {
this.barcodeScanner.scan().then((result) => {
if (!result.cancelled) {
this.barcodeText = result.text;
this.scanningDone(this.barcodeText)
}
}, (error) => {
console.log('error when scanning product barcode');
});
});
}
scanningDone(data){
this.navController.push(TabsPage,{
data:data
});
}
main.ts where the info suppose to go:
import { Component } from '#angular/core';
import { NavController, NavParams , ToastController} from 'ionic-angular';
import { BarcodeScanner } from '#ionic-native/barcode-scanner';
import { DetailsPage } from '../details/details';
import { Http } from '#angular/http'
#Component({
selector: 'main',
templateUrl: 'main.html'
})
export class MainPage {
information: any[];
item:any;
private bcData;
constructor(public navCtrl: NavController, private http: Http,public params:NavParams) {
this.bcData = params.get('data');
console.log(params.get('data'));
let localData = http.get(this.bcData).map(res => res.json().items);
localData.subscribe(data => {
this.information = data;
})
}
on the console.log(params.get('data')); its where I get the undefinied on the console.
you could have a method in your TabsPage that handles opening and closing pages like this:
openPages(Page, Data){
this.navCtrl.push(Page,Data);
}
Then in your scanningDone Method:
scanningDone(data){
this.tabsPage.openPages(MainPage,{
data:data
});
}
How about using localStorage
look at this as well

Ionic 2: Facebook Login -> Error: No Provider in NavController (TypeScript)

I've been working on the facebook login for my ionic 2 app
(used this tutorial: https://ionicthemes.com/tutorials/about/ionic2-facebook-login)
But now i get a weird error:
RunTimeError Error in :0:0 caused by: No provider for NavController
app.component.ts:
import { Component } from '#angular/core';
import { Platform } from 'ionic-angular';
import { StatusBar } from '#ionic-native/status-bar';
import { SplashScreen } from '#ionic-native/splash-screen';
import { NativeStorage } from '#ionic-native/native-storage';
import { TabsPage } from '../pages/tabs/tabs';
import { WelcomePage } from '../pages/welcome/welcome';
import { DetailPage } from '../pages/detail/detail';
#Component({
templateUrl: 'app.html'
})
export class MyApp {
rootPage: any = WelcomePage;
constructor(NativeStorage: NativeStorage, platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen) {
platform.ready().then(() => {
// Here we will check if the user is already logged in
// because we don't want to ask users to log in each time they open the app
let env = this;
NativeStorage.getItem('user')
.then((data) => {
// user is previously logged and we have his data
// we will let him access the app
this.rootPage = DetailPage;
splashScreen.hide();
}, (error) => {
//we don't have the user data so we will ask him to log in
this.rootPage = WelcomePage;
splashScreen.hide();
});
statusBar.styleDefault();
});
}
}
welcome.ts:
import { Component } from '#angular/core';
import { Facebook, NativeStorage } from 'ionic-native';
import { NavController } from 'ionic-angular';
import { DetailPage } from '../detail/detail';
import { ViewChild } from '#angular/core';
#Component({
selector: 'page-welcome',
templateUrl: 'welcome.html'
})
export class WelcomePage {
rootPage: any = WelcomePage;
#ViewChild('navRoot') navCtrl: NavController;
FB_APP_ID: number = 123456789;
constructor() {
Facebook.browserInit(this.FB_APP_ID, "v2.8");
}
doFbLogin() {
let permissions = new Array();
let nav = this.navCtrl;
//the permissions your facebook app needs from the user
permissions = ["public_profile"];
Facebook.login(permissions)
.then(function (response) {
let userId = response.authResponse.userID;
let params = new Array();
//Getting name and gender properties
Facebook.api("/me?fields=name,gender", params)
.then(function (user) {
user.picture = "https://graph.facebook.com/" + userId + "/picture?type=large";
//now we have the users info, let's save it in the NativeStorage
NativeStorage.setItem('user',
{
name: user.name,
gender: user.gender,
picture: user.picture
})
.then(function () {
nav.push(DetailPage);
}, function (error) {
console.log(error);
})
})
}, function (error) {
console.log(error);
});
}
}
You cannot import NavController in app.component.ts or the root app page.
OPTION 1:
Try to get it using ViewChild
Give element id to root-nav
<ion-nav #navRoot [root]="rootPage"></ion-nav>
In component:
import {ViewChild} from '#angular/core';
#Component({
templateUrl: 'app.html'
})
export class MyApp {
rootPage: any = WelcomePage;
#ViewChild('navRoot') navCtrl:NavController;
constructor(nativeStorage: NativeStorage, platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen) { //remove navcontroller injected
platform.ready().then(() => {
// Here we will check if the user is already logged in
// because we don't want to ask users to log in each time they open the app
let env = this;
//...
OPTION 2:
From your app.component.ts code, you dont actually need to import NavController at all if your html template only contains,
<ion-nav [root]="rootPage"></ion-nav>
Simply set the required page to rootPage.
nativeStorage.getItem('user')
.then( (data) => {
// user is previously logged and we have his data
// we will let him access the app
this.rootPage = DetailPage;
splashScreen.hide();
}, (error) => {
//we don't have the user data so we will ask him to log in
this.rootPage = WelcomePage;
splashScreen.hide();
});
Side Note: Better to use ()=>{} arrow functions for callbacks instead of saving context in second variable.

AngularJS 2 Typescript interface

I have a service for handling users operations and an interface for the user object.
user.service.ts
import {Injectable} from 'angular2/core';
export interface User {
name: string;
email?: string;
picture?: string;
}
#Injectable()
export class UserService {
me: User;
constructor() {
}
setUser(user: User) {
this.me = user;
}
}
In my login component I try to set the user with the profile returned from the login service but I get this error:
Property 'firstName' does not exist on type '{}'.
login.component.ts
import {Component} from 'angular2/core';
import {User, UserService} from './services/user.service';
import {LinkedinService} from './services/linkedin.service';
declare const IN: any;
console.log('`Login` component loaded asynchronously');
#Component({
selector: 'Login',
providers: [
UserService,
LinkedinService
],
template: require('./login.html')
})
export class LoginComponent {
me: User;
constructor(public linkedinService: LinkedinService, public userService: UserService) {
this.me = userService.me;
}
ngOnInit() {
console.log('hello `Login` component');
}
login() {
this.linkedinService.login()
.then(() => this.linkedinService.getMe()
.then(profile => this.userService.setUser({ name: profile.firstName })));
}
}
linkedin.service.ts
import {Injectable} from 'angular2/core';
declare const IN: any;
#Injectable()
export class LinkedinService {
constructor() {
IN.init({
api_key: 'xxxxxxxxxxx',
authorize: true
});
}
login() {
return new Promise((resolve, reject) => {
IN.User.authorize(() => resolve());
});
}
getMe() {
return new Promise((resolve, reject) => {
IN.API.Profile('me').result((profile) => resolve(profile.values[0]));
});
}
}
I'm trying to import the User interface from UserService and use inside the LoginComponent but I don't know what I'm doing wrong. Any idea? I am not sure if I have to use the User interface inside the LoginComponent, is that right?
Narrow in on the code :
.then(() => this.linkedinService.getMe())
.then(profile => this.userService.setUser({ name: profile.firstName })));
The type of profile is driven by the response of this.linkedinService.getMe(). Seems like it is something like Promise<{}>. It does not have the member firstName. Hence the error:
Property 'firstName' does not exist on type '{}'.
Fix
Check to the code / signatures of linkedinService. This has nothing to do with the user.service.ts file that the question contains 🌹
Update
Focus in on the code:
getMe() {
return new Promise((resolve, reject) => {
IN.API.Profile('me').result((profile) => resolve(profile.values[0]));
});
}
The value returned is driven by what is being passed to resolve. So make sure profile.values[0] has the right type. Alternatively provide the hint to the compiler:
getMe() {
return new Promise<{firstName:string}>((resolve, reject) => {
IN.API.Profile('me').result((profile) => resolve(profile.values[0]));
});
}