Unresolved function .map in ionic 2 RC0 project - ionic2

I am getting an 'unresolved function' error for a .map in an ionic 2 RC0 project.
The code looks like this:
import {Injectable} from '#angular/core';
import {Events} from 'ionic-angular';
import {Http, RequestOptions} from '#angular/http';
import {API_ENDPOINT} from '../app_settings';
import {DjangoAuth} from '../providers/djangoAuth';
import 'rxjs/add/operator/map';
#Injectable()
export class ImageData {
userID:number = 0;
data:any;
httpBody:any;
constructor(public http: Http, public events: Events, public djangoAuth: DjangoAuth) {
}
loadImages(theUserID, numberItemsToGet, feedType){
var additional_parameters = '';
var theCategoriesWanted = 'ALL';
if (feedType == 'USERS'){
additional_parameters = '&fromthisuser=true';
theCategoriesWanted = 'ALL';
}
else if (feedType == 'UNSEEN'){
additional_parameters = '';
}
else if (feedType == 'BOOKMARKS'){
additional_parameters = '&bookmarked=True'+this.userID;
theCategoriesWanted = 'ALL';
}
return this.djangoAuth.createHeaders(true).then((headers) => {
var options = new RequestOptions({headers: headers, withCredentials: this.djangoAuth.use_session});
return new Promise(resolve => {
this.http.get(API_ENDPOINT + 'items/?categories=' + theCategoriesWanted + '&num=' + numberItemsToGet + '&user=' + this.userID + '&format=json' + additional_parameters, options)
.map(res => res.json())
.subscribe(
(data: any) => {
this.data = data;
resolve(this.data);
},
(err: any) => {
resolve("api/items returned error: " + err);
},
() => {
//alert('Complete');
}
);
});
});
}
This code used to work before I updated to ionic 2 RC0.

Try updating your IDE to use Typescript 2.0.3 and ECMAScript6
This worked for me.

Related

React Testing, using axios-mock-adapter

I need to switch out my backend in-memory DB for testing due to memory issues. Below is my code
import { fireEvent, render, screen, waitFor } from "#testing-library/react";
import userEvent from "#testing-library/user-event";
import App from "App";
import axios from "axios";
import MockAdapter from "axios-mock-adapter";
import { AccessLevel, ResponseApi, SystemUserApi } from "types";
let mock: MockAdapter;
beforeAll(() => {
mock = new MockAdapter(axios);
});
afterEach(() => {
mock.reset();
});
beforeEach(() => {
jest.resetModules();
});
describe("<App />", () => {
test("login", async () => {
mock.onPost('/Hello').reply(200, getPost);
const result = render(<App />);
const user = userEvent.setup();
const btnLogin = screen.getByText(/Login/i) as HTMLButtonElement;
await userEvent.click(btnLogin);
let btnOk = screen.queryByText(/OK/i) as HTMLButtonElement;
expect(btnOk.disabled).toBe(true);
let btnCancel = screen.getByText(/Cancel/i) as HTMLButtonElement;
expect(btnCancel.disabled).toBe(false);
fireEvent.change(screen.getByLabelText(/Access Code/i) as HTMLInputElement, { target: { value: 'USER' } });
expect(btnOk.disabled).toBe(false);
await userEvent.click(btnOk);
//At this point I was expecting the onPost to be clicked
});
});
function getPost(config: any): any {
console.log(config);
debugger;
return {
data: {
access_code: 'USER'.toUpperCase(),
access_level: AccessLevel.USER ,
lock_level:true
} as SystemUserApi,
error: false,
} as ResponseApi
}
Deep down in the is a call axios post to /Hello but my function within the test is not called. I do not know if it has to do with the actual call being axios.request vs axios.post. I have tried switching to mock.onAny, but that did not seem to work. Not sure what to do here.

Unit Test in NestJs using Jest

So, I want to test a Controller, but I always get the same error, and I not really familiarized with Jest.
I work with php and I already did some unit tests in phpUnit, but with Jest I'm really having some trouble to understand how to do.
Here is my error message
● Test suite failed to run
SyntaxError: /home/webjump-nb103/Projects/development/workspace/stare/customer/src/customer/customer.controller.spec.ts: Unexpected token, expected ";" (13:26)
11 |
12 | describe('Customer Controller', () => {
> 13 | let customerController: CustomerController;
| ^
14 | let customerService: CustomerService;
15 |
16 | beforeAll(async () => {
at Parser.raise (node_modules/#babel/parser/src/parser/location.js:41:63)
at Parser.unexpected (node_modules/#babel/parser/src/parser/util.js:150:16)
at Parser.semicolon (node_modules/#babel/parser/src/parser/util.js:123:40)
at Parser.parseVarStatement (node_modules/#babel/parser/src/parser/statement.js:703:10)
at Parser.parseStatementContent (node_modules/#babel/parser/src/parser/statement.js:216:21)
at Parser.parseStatement (node_modules/#babel/parser/src/parser/statement.js:146:17)
at Parser.parseBlockOrModuleBlockBody (node_modules/#babel/parser/src/parser/statement.js:865:25)
at Parser.parseBlockBody (node_modules/#babel/parser/src/parser/statement.js:841:10)
at Parser.parseBlock (node_modules/#babel/parser/src/parser/statement.js:818:10)
at Parser.parseFunctionBody (node_modules/#babel/parser/src/parser/expression.js:1964:24)
My controller
import {Controller, HttpStatus, Post, Res, Body, ValidationPipe, Put, Param, Get} from '#nestjs/common';
import {CreateCustomerDto} from './dto/customer/customer.dto';
import {CustomerService} from './customer.service';
#Controller('customer')
export class CustomerController {
constructor(private readonly customerService: CustomerService) { }
#Post()
async createPost(#Res() res, #Body(ValidationPipe) createCustomerDto: CreateCustomerDto ) {
const customer = await this.customerService.createCustomer(createCustomerDto);
return res.status(HttpStatus.OK).json({
customer: customer
});
}
#Put('update/:id')
async createUpdate(#Param('id') id: string, #Res() res, #Body(ValidationPipe) createCustomerDto: CreateCustomerDto) {
const customer = await this.customerService.updateCustomer(createCustomerDto, id);
return res.status(HttpStatus.OK).json({
customer: customer
});
}
}
**My Service **
import {Injectable} from '#nestjs/common';
import {Model} from 'mongoose';
import {InjectModel} from '#nestjs/mongoose';
import {Customer} from './interfaces/customer.interface';
import {CreateCustomerDto} from './dto/customer/customer.dto';
#Injectable()
export class CustomerService {
constructor(#InjectModel('customer') private readonly customerModel: Model<Customer>) {}
async createCustomer(createCustomerDto: CreateCustomerDto ): Promise<Customer> {
const customer = new this.customerModel(createCustomerDto);
return customer.save();
}
async updateCustomer(createCustomerDto: CreateCustomerDto, id: string): Promise<Customer> {
const customer = await this.customerModel
.findByIdAndUpdate(id, createCustomerDto, {new: true});
return customer;
}
}
And my test
import { Test, TestingModule } from '#nestjs/testing';
import { CustomerController } from './customer.controller';
import {CustomerService} from './customer.service';
import {CreateCustomerDto} from './dto/customer/customer.dto';
import {Customer} from './interfaces/customer.interface';
import {InjectModel} from '#nestjs/mongoose';
jest.mock('./customer.service.ts');
jest.mock('./customer.controller.ts');
jest.mock('./interfaces/customer.interface.ts');
describe('Customer Controller', () => {
let customerController: CustomerController;
let customerService: CustomerService;
beforeAll(async () => {
const module = await Test.createTestingModule({
controllers: [CustomerController],
providers: [CustomerService],
}).compile();
customerController = module.get(CustomerController);
customerService = module.get<CustomerService>(CustomerService);
});
describe('Create Post', () => {
const dto = new CreateCustomerDto();
const res = 200;
const customerModel: Customer;
it('should return an collection of customer when created ', async () => {
const expectedResult = new CustomerService(#InjectModel(customerModel<Customer>));
jest.spyOn(customerService, 'createCustomer').mockResolvedValue(customerModel);
expect(await customerController.createPost(res, dto)).toBe(expectedResult);
});
});
});
**Any thoughts ?**
As already mentioned in the comments, make sure you have your jest properly configured. Try to add/modify the following to your package.json
"jest": {
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "src",
"testRegex": ".spec.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"coverageDirectory": "../coverage",
"testEnvironment": "node"
}

Ionic 2 Providers

I am upgrading my app from Ionic 2.0.0-beta.20 to Ionic 2.0.0-rc.3 using this guide.
I have an issue regarding a provider called RatingService, which I am a little confused about, if anyone can assist, I would appreciate it.
Problem
I get the following error in app.module.ts.
[ts] Argument of type '{ declarations: any[]; imports: ModuleWithProviders[]; bootstrap: typeof IonicApp[]; entryCompone...' is not assignable to parameter of type 'NgModule'.
Types of property 'providers' are incompatible.
Type '{ provide: typeof ErrorHandler; useClass: typeof IonicErrorHandler; RatingService: typeof RatingS...' is not assignable to type 'Provider[]'.
Type '{ provide: typeof ErrorHandler; useClass: typeof IonicErrorHandler; RatingService: typeof RatingS...' is not assignable to type 'Provider'.
Object literal may only specify known properties, and 'RatingService' does not exist in type 'Provider'.
I think I need to make use of provide: and useClass: for each provider, but I'm not sure what these values should be?
Code
app.module.ts
import { RatingService } from '../pages/service/ratingService';
...
providers: [{ provide: ErrorHandler,
useClass: IonicErrorHandler,
RatingService,
JobService,
UtilityService,
...
ratingService.ts
import { Injectable, Inject } from "#angular/core";
import { RatingModel } from '../model/RatingModel';
import { NavController } from 'ionic-angular';
import { Http, Headers } from "#angular/http"
import { ParentService } from "../service/parentService";
import 'rxjs/add/operator/map';
#Injectable()
export class RatingService extends ParentService {
public BASE_URI: String = super.getBaseUrl()+'/rating';
public http: Http = null;
constructor( #Inject(Http) http: Http) {
super();
this.http = http;
}
getRatingRange(firstResult: number, maxResults: number): Promise<RatingModel[]> {
return new Promise<RatingModel[]>(resolve => {
this.getRatingRangeHttpCall(firstResult, maxResults).subscribe(
data => {
var ratingModels: RatingModel[] = [];
for (var index = 0; index < data.length; index++) {
var element = data[index];
ratingModels.push(element);
}
resolve(ratingModels);
},
error => alert('RatingRangeDataPromise(' + firstResult + ', ' + maxResults + ') Data not available. Please try again.\n' + error),
() => {
});
});
}
getRatingForJobRange(firstResult: number, maxResults: number, jobId: number): Promise<RatingModel[]> {
return new Promise<RatingModel[]>(resolve => {
this.getRatingRangeForJobHttpCall(firstResult, maxResults, jobId).subscribe(
data => {
var ratingModels: RatingModel[] = [];
for (var index = 0; index < data.length; index++) {
var element = data[index];
ratingModels.push(element);
}
resolve(ratingModels);
},
error => alert('RatingForJobRange(' + firstResult + ', ' + maxResults + ', ' + jobId + ') Data not available. Please try again.\n' + error),
() => {
});
});
}
saveRating(ratingModel: RatingModel): Promise<RatingModel> {
return new Promise<RatingModel>(resolve => {
this.saveRatingHttpCall(ratingModel).subscribe(
data => {
resolve(data);
},
error => alert('Save Unsuccesfull.\n' + error),
() => {
});
});
}
getRating(id: number): Promise<RatingModel> {
return new Promise<RatingModel>(resolve => {
this.getRatingHttpCall(id).subscribe(
data => {
resolve(data);
},
error => alert('getRating Data not available. Please try again.\n' + error),
() => {
//console.log("Finished getRating");
});
});
}
public getRatingRangeHttpCall(firstResult: number, maxResults: number) {
return this.http.get(this.BASE_URI + '/list/range/' + firstResult + '/' + maxResults)
.map(res => res.json());
}
public getRatingRangeForJobHttpCall(firstResult: number, maxResults: number, jobId: number) {
return this.http.get(this.BASE_URI + '/list/range/' + firstResult + '/' + maxResults + '/' + jobId)
.map(res => res.json());
}
public saveRatingHttpCall(ratingModel: RatingModel) {
var headers = new Headers();
headers.append('Accept', 'application/json');
headers.append('Content-Type', 'application/json');
return this.http.post(this.BASE_URI + '/save', ratingModel, {
headers: headers
})
.map(res => res.json());
}
public getRatingHttpCall(id: number) {
return this.http.get(this.BASE_URI + '/list/' + id)
.map(res => res.json());
}
}
parentService.ts
import { Injectable, Inject } from "#angular/core";
#Injectable()
export class ParentService {
public PARENT_BASE_URI: string = 'http://localhost:8080/jbosswildfly';
//public PARENT_BASE_URI: string = 'http://jbosswildfly-easypeasy.rhcloud.com';
constructor() {
}
public getBaseUrl(): string {
return this.PARENT_BASE_URI;
}
}
UPDATE
I have changed the code to the following, I will test it to see if it works:
providers: [
{ provide: ErrorHandler, useClass: IonicErrorHandler},
{ provide: RatingService, useClass: RatingService},
{ provide: JobService, useClass: JobService},
{ provide: UtilityService, useClass: UtilityService}
]
should be :
providers: [{ provide: ErrorHandler,
useClass: IonicErrorHandler},
RatingService,
JobService,
UtilityService,
You can also get this error if you accidentally use
import RatingService from '../pages/service/ratingService';
instead of
import { RatingService } from '../pages/service/ratingService';
That typo cost me 2 hours so I'm adding this answer in the hope that it saves someone else the same frustration.

cordova.fileTransfer not updating page template Ionic2+Cordova

I have created an Ionic2 App using cordova FileTransferplugin, i am downloading remote server file.
Everything is working perfectly, but when I try to update template while fileTransfer.OnProgress event, the template is not updating the % downloaded.
Pleas see this video for my problem.
Ionic_youtube_link
My Code is, logic is in downloadFile function
import {Component, AfterViewInit, ViewChild} from '#angular/core';
import {NavController, NavParams, ViewController, Nav} from 'ionic-angular';
import {Page, Platform} from 'ionic-angular';
import {File, Device, Cordova, Transfer} from 'ionic-native';
import { SafeResourceUrl, DomSanitizationService } from '#angular/platform-browser';
#Component({
templateUrl: 'build/pages/video-download-modal/video-download-modal.html',
providers: [File, Transfer]
})
export class VideoDownloadModal {
selectedItem: any;
#ViewChild(Nav) nav: Nav;
videoPathUrl: string;
isPlatformReady: boolean;
platformName: string;
directoryName: string = "socialAppDir";
totalVideoSize:number;
totalDownloaded:number;
totalPercent:string = "0%";
constructor(public navCtrl: NavController, navParams: NavParams, private _viewController: ViewController, platform: Platform, private transfer:Transfer) {
// If we navigated to this page, we will have an item available as a nav param
if (platform.is('core')) {//if on dekstop
console.log('dektop');
} else {
this.videoPathUrl = navParams.get('videoPath');
console.log(this.videoPathUrl);
platform.ready().then((readySource) => {
this.isPlatformReady = true;
console.log('ready 1234');
const fs: string = cordova.file.externalRootDirectory;
console.log(cordova.file.dataDirectory);
this.platformName = Device.device.platform;
File.checkDir(cordova.file.externalDataDirectory, this.directoryName).then(() => {
console.log('directory exists');
this.downloadFile();
}, (error) => {
console.log('directory not exists');
this.createDirectory();
})
})
}
}
dismiss() {
let data = { 'foo': 'bar' };
this._viewController.dismiss(data);
}
createDirectory():void{
File.createDir(cordova.file.externalDataDirectory, this.directoryName, true).then(() => {
console.log("created externalDataDirectory");
this.downloadFile();
},(error) => {
console.log('some error happen')
})
}
downloadFile = () => {
console.log(this);
let fileName: string = this.videoPathUrl.split("/").pop();
let targetPath = cordova.file.externalDataDirectory + this.directoryName + "/" + fileName;
console.log(targetPath);
this.transfer.download(this.videoPathUrl, targetPath, true, {}).then(() => {
console.log('video downloaded')
}, (error) => {
console.log(error)
})
this.transfer.onProgress((progress) => {
console.log(this);
this.totalVideoSize = progress.total;
this.totalDownloaded = progress.loaded;
this.totalPercent = ((progress.loaded / progress.total) * 100).toString();
console.log(this.totalPercent);
})
}
ionViewDidEnter() {
console.log("enter login1");
}
}
And HTML is
<ion-content>
<div id="modalContainer" class="abd">
<ion-spinner></ion-spinner>
<br />
{{**totalPercent**}}
<br />
<button dnager block (click)="dismiss()">Exit</button>
</div>
</ion-content>
The totalPercent value either has 0 or 100.But not updating.
Please help.
This is because the totalPercent of this inside the handler was set to the global Window object instead of the object itself.
I have finally got it to work
import { NgZone } from '#angular/core';
fileTransfer.onProgress((progressEvent: ProgressEvent) => {
this.ngZone.run(() => {
if (progressEvent.lengthComputable) {
let lp = progressEvent.loaded / progressEvent.total * 100;
this.loadingPercent = Math.round(lp * 100) / 100;
}
});
})

Angular2, Ionic2 post to web service

import {Page, Platform} from 'ionic-angular';
import { Http, Headers, Response, RequestOptions, HTTP_PROVIDERS} from 'angular2/http';
import { bootstrap } from 'angular2/platform/browser';
import { Component, Injectable, Inject } from 'angular2/core';
import 'rxjs/Rx';
import { CORE_DIRECTIVES, FORM_DIRECTIVES } from 'angular2/common';
import {Observable} from 'rxjs/Observable';
#Page({
directives: [ CORE_DIRECTIVES, FORM_DIRECTIVES ],
templateUrl: 'build/pages/getting-started/getting-started.html'
})
#Injectable()
export class GettingStartedPage {
public platform;
public networkState;
private headers;
private _apiUrl = 'http://172.16.2.115:3004/message';
subject: string;
message: string;
comments: string;
constructor(platform: Platform, public http: Http) {
this.platform = platform;
this.headers = new Headers();
this.headers.append('Content-Type', 'application/x-www-form-urlencoded');
}
onSubmit(value) {
this.send(value.subject, value.body);
}
send(subject, body)
{
var message = "subject=" + subject + "&body=" + body;
let result = this.http.post(this._apiUrl,
body,
{
headers: this.headers
}).map(res => {
this.comments = res.json();
});
this.send(subject, body).subscribe(res => {
console.log(message);
console.log(this._apiUrl);
});
return result;
}
}
I am trying to create a mobile app using Ionic2 and Angular2 beta.This app will send an email using POST to a Rails web service. The Rails web service is working just fine. I dont seem to be getting to work the mobile app.
There was a misunderstanding
this.send(subject, body).subscribe(res => {
console.log(message);
console.log(this._apiUrl);
});
would be in a different method
onSubmit(value) {
this.send(value.subject, value.body)
.subscribe(res => {
console.log(message);
console.log(this._apiUrl);
});
}
send(subject, body)
{
var message = "subject=" + subject + "&body=" + body;
return this.http.post(this._apiUrl,
body,
{
headers: this.headers
}).map(res => {
this.comments = res.json();
});
}
You should refactor your code this way:
onSubmit(value) {
this.send(value.subject, value.body).subscribe(res => {
console.log(message);
console.log(this._apiUrl);
});
}
send(subject, body)
{
var message = "subject=" + subject + "&body=" + body;
let result = this.http.post(this._apiUrl,
body,
{
headers: this.headers
}).map(res => {
this.comments = res.json();
});
return result;
}