Why are Crashlytics functions undefined? - ionic-framework

I have installed the cordova-fabric-plugin in my Ionic 2 project. After that, I have extended IonicHandlerError in FabricHandlerError (code below). The problem is that when the cached error arrives, the Crashlytics is defined and all functions appears in console, but when you use that, they are undefined.
import {Injectable} from "#angular/core";
import {IonicErrorHandler } from 'ionic-angular';
import { Crashlytics } from '#ionic-native/fabric';
#Injectable()
export class FabricErrorHandler extends IonicErrorHandler {
constructor (public crashlytics: Crashlytics) {
super();
}
handleError(error: any): void {
console.log('In Fabric Error Handler');
console.log(error);
this.crashlytics.addLog(error.message);
this.crashlytics.sendCrash();
console.log('Crashlytics Sended. Error message: '+ error.message);
super.handleError(error);
}
}
In console stopping in handler error:
this.crashlytics
Crashlytics {}
__proto__: IonicNativePlugin
addLog: ƒ ()
constructor: ƒ Crashlytics()
recordError: ƒ ()
sendCrash: ƒ ()
sendNonFatalCrash: ƒ ()
setBoolValueForKey: ƒ ()
setFloatValueForKey: ƒ ()
setIntValueForKey: ƒ ()
setStringValueForKey: ƒ ()
setUserEmail: ƒ ()
setUserIdentifier: ƒ ()
setUserName: ƒ ()
__proto__: Object
this.crashlytics.addLog('ERROR TESTING');
undefined
this.crashlytics.sendCrash();
undefined

Related

Problem calling mongoose service with nestjs in jest testing

Currently i'm trying to test my service but always fails and prints the error, even when the app is running correctly and the service is working
Error
TypeError: undefined is not a function
at Array.find (<anonymous>)
at NewsService.findAll (MY_ROUTE\src\news\news.service.ts:28:8)
at Object.it (MY_ROUTE\src\news\news.service.spec.ts:33:10)
at Object.asyncJestTest (MY_ROUTE\node_modules\jest-jasmine2\build\jasmineAsyncInstall.js:106:37)
at resolve (MY_ROUTE\node_modules\jest-jasmine2\build\queueRunner.js:45:12)
at new Promise (<anonymous>)
at mapper (MY_ROUTE\node_modules\jest-jasmine2\build\queueRunner.js:28:19)
at promise.then (MY_ROUTE\node_modules\jest-jasmine2\build\queueRunner.js:75:41)
at process._tickCallback (internal/process/next_tick.js:68:7)
at service.findAll.then.catch (news/news.service.spec.ts:39:19)
news.service.spec.ts
import { NewsService } from './news.service';
import { Model } from 'mongoose';
import { News, NewsSchema } from './schemas/news.schema';
import { getModelToken } from '#nestjs/mongoose';
describe('NewsService', () => {
let service: NewsService;
const mockRepository = (...args: any[]) => { };
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [NewsService, { provide: getModelToken(News.name), useFactory: mockRepository }],
}).compile();
service = module.get<NewsService>(NewsService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
describe('get news', () => {
it('should get all news', async () => {
service
.findAll()
.then((allNews) => {
console.log(allNews);
expect(allNews).toBeDefined();
})
.catch((error) => {
console.log(error);
});
});
});
});
news.schema.ts
import { Document } from 'mongoose';
export type NewsDocument = News & Document;
#Schema()
export class News extends Document {
#Prop({ unique: true })
id: string;
#Prop()
title: string;
#Prop()
date: string;
}
export const NewsSchema = SchemaFactory.createForClass(News);
news.service.ts
import { Model } from 'mongoose';
import { InjectModel } from '#nestjs/mongoose';
import { News } from './schemas/news.schema';
#Injectable()
export class NewsService {
constructor(
#InjectModel(News.name) private readonly newsModel: Model<News>
) {}
public async findAll(): Promise<News[]> {
return await this.newsModel
.find()
.sort([['date', 'descending']])
.exec();
}
}
I'm just learning about Jest, but after a lot of research and tests, i couldn't figured out what i'm doing wrong exactly.
EDIT
This is the only "decent" thing that i've tried to, but other errors appear. Maybe my whole focus on this is wrong.
const mockRepository = (...args: any[]) => {
findAll: jest.fn().mockReturnValue([
new News({
id: '1',
title: 'title',
date: 'date',
}),
]);
};
Error
TypeError: Cannot read property 'plugin' of undefined
5 |
6 | #Schema()
> 7 | export class News extends Document {
| ^
8 | #Prop({ unique: true })
9 | id: string;
10 |
at News.Object.<anonymous>.Document.$__setSchema (../node_modules/mongoose/lib/document.js:3028:10)
at new Document (../node_modules/mongoose/lib/document.js:86:10)
at new News (news/schemas/news.schema.ts:7:1)
at InstanceWrapper.mockRepository [as metatype] (news/news.service.spec.ts:13:7)
at Injector.instantiateClass (../node_modules/#nestjs/core/injector/injector.js:293:55)
at callback (../node_modules/#nestjs/core/injector/injector.js:77:41)

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

Ionic 2 HTTP request not working - Angular 2

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

$firebaseArray is empty with ionic

I am trying to load data in firebase with $firebaseArray as:
var ref = new Firebase(FURL);
var eventRef = ref.child('event');
$scope.events= $firebaseArray(eventRef)
I have event data in my firebase. But my $scope.events returns:
[]
0: Object
$$added: ()
$$error: ()
$$getKey: ()
$$moved: ()
$$notify: ()
$$process: ()
$$removed: ()
$$updated: ()
$add: ()
$destroy: ()
$getRecord: ()
$indexFor: ()
$keyAt: ()
$loaded: ()
$ref: ()
$remove: ()
$save: ()
$watch: ()
length: 0__proto__: Array[0]
what is possible reason?
Possible Reason You are accessing data before it is is loaded.
You must wait till data is loaded, Rewrite your code this way:
var ref = new Firebase(FURL);
var eventRef = ref.child('event');
$scope.events = $firebaseArray(eventRef);
$scope.events.$loaded()
.then(function(){
// access events here;
});

Why do my socket.on calls multiply whenever i recenter my controller

I've been using the socket factory described here by the brian ford here
http://www.html5rocks.com/en/tutorials/frameworks/angular-websockets/
here is the factory
myApp.factory('socket', function ($rootScope) {
var socket = io.connect('url');
return {
on: function (eventName, callback) {
socket.on(eventName, function () {
var args = arguments;
$rootScope.$apply(function () {
callback.apply(socket, args);
});
});
},
emit: function (eventName, data, callback) {
socket.emit(eventName, data, function () {
var args = arguments;
$rootScope.$apply(function () {
if (callback) {
callback.apply(socket, args);
}
});
})
}
};
});
I have a socket.emit in my controllers initialization function and whenever i reenter this controller from another page the receiving socket.on function executes +1 times. This happens until I manually refresh the page then it resets to 1. I don't explicitly store my socket in session. So what could be causing my socket.on to call multiple times.
Here is my socket.emt in my controller
this always executes once.
$scope.init = funciton (){
...
socket.emit('getSignedSlidesFromUrl', $scope.slideLocation);
}
Here is my socket.on that will be recieve 'getSignedSlidesFromUrl'
socket.on('signedUrls', function (signedSlides){
console.log('signedUrls socket hit');
$scope.slides = signedSlides;
console.log($scope.slides[0]);
console.log($scope.display);
});
Here is an example of my console log after reentering the controller
about to emit getSignedSlidesFromUrl from init controllers.js:71
display after called $scope.first slide is0 controllers.js:574
flash object is controllers.js:537
signedUrls socket hit controllers.js:816
0 controllers.js:823
signedUrls socket hit controllers.js:816
0 controllers.js:823
if I reenter the controller again my log would change to
signedUrls socket hit controllers.js:816
0 controllers.js:823
signedUrls socket hit controllers.js:816
0 controllers.js:823
signedUrls socket hit controllers.js:816
0 controllers.js:823
You have to add removeAllListeners to your factory (see below) and have the following code in each of your controllers:
$scope.$on('$destroy', function (event) {
socket.removeAllListeners();
});
Updated socket factory:
var socket = io.connect('url');
return {
on: function (eventName, callback) {
socket.on(eventName, function () {
var args = arguments;
$rootScope.$apply(function () {
callback.apply(socket, args);
});
});
},
emit: function (eventName, data, callback) {
socket.emit(eventName, data, function () {
var args = arguments;
$rootScope.$apply(function () {
if (callback) {
callback.apply(socket, args);
}
});
})
},
removeAllListeners: function (eventName, callback) {
socket.removeAllListeners(eventName, function() {
var args = arguments;
$rootScope.$apply(function () {
callback.apply(socket, args);
});
});
}
};
});
I tried #michaeljoser's solution, but it didn't work for me.
Then I found another solution and it worked
var socket = io.connect('url');
return {
on: function (eventName, callback) {
socket.on(eventName, function () {
var args = arguments;
$rootScope.$apply(function () {
callback.apply(socket, args);
});
});
},
emit: function (eventName, data, callback) {
socket.emit(eventName, data, function () {
var args = arguments;
$rootScope.$apply(function () {
if (callback) {
callback.apply(socket, args);
}
});
})
},
getSocket: function(){
return socket;
}
};
});
And in controller, I called
$scope.$on('$destroy', function (event) {
socket.getSocket().removeAllListeners();
});