How to image upload in ionic 2 using REST API - ionic2

Without Ani transfer ionic 2 plugin
How to image upload in ionic 2 using REST API

public options: CameraOptions = {
enter code herequality: 100,
sourceType: this.camera.PictureSourceType.PHOTOLIBRARY,
destinationType: this.camera.DestinationType.FILE_URI,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,
saveToPhotoAlbum: true,
allowEdit:true,
correctOrientation:true,
targetWidth:300,
targetHeight:150
}
takePicture(options){
this.camera.getPicture(options).then((imageData) => {
console.log("imageData",imageData);
this.base64Image = imageData;
}, (err) => {
console.log(err);
});
}
add(){
var formData={
"title" : this.title,
"image" : this.base64Image,
"description" : this.description
}
if(this.formgroup.valid == true){
this.presentLoadingDefault();
this.service.add(formData).subscribe(
(data)=>{
console.log('data',data);
if(data.Code == 200){
this.presentToast(data.Message);
}else{`enter code here`
this.presentToast(data.Message);
}
this.loading.dismiss();
this.navCtrl.pop();
},
function (error){
console.log("error"+error)
});
}
}

Install the Cordova and Ionic Native plugins:
ionic cordova plugin add cordova-plugin-camera
npm install --save #ionic-native/camera
import {Camera, File, CameraOptions} from "ionic-native";
import { Myservice } from '../../providers/myservice';
export class HomePage {
captureDataUrl:any;
constructor(private Service:Myservice){}
openCamera() {
const cameraOptions: CameraOptions = {
targetHeight:150,
targetWidth:150,
allowEdit:true,
quality: 50,
destinationType: Camera.DestinationType.DATA_URL,
encodingType: Camera.EncodingType.JPEG,
mediaType: Camera.MediaType.PICTURE,
};
Camera.getPicture(cameraOptions).then((imageData) => {
this.captureDataUrl = 'data:image/jpeg;base64,' + imageData;
console.log("CaptureDataUrl:" + this.captureDataUrl);
this.upload();
}, (err) => {
});
}
this.upload(){
var profildata={
"name" :'HR PATEL',
"image" : this.base64Image
}
this.Service.getSaveImage(profildata).subscribe(
response => {
console.log("user add sucessfully");
},
err => {
console.log("err...."+err );
}
);
}
}
// call the myservice.ts
import { Http, Headers } from '#angular/http';
import {Observable} from 'rxjs/Observable';
#Injectable()
export class Myservice {
constructor(public http: Http){}
getSaveImage(profiledata): Observable<any>{
let headers = new Headers({'Content-Type': 'application/x-www-form-urlencoded'});
return this.http.post("this api url",{data:profiledata},{headers:headers})
.map(data=> data.json());
}
}
}

Related

How to mock an inject repository with Jest and NestJS?

In a NestJS project using Jest test the service case. I created a find method and use it in a resolver(GraphQL) function. When test the resolver, it can't find the find method in the service.
src/serivce/post.ts
import { Injectable } from '#nestjs/common';
import { InjectRepository } from '#nestjs/typeorm';
import { AbstractPostRepository } from '#abstractRepository/AbstractPostRepository';
import { PostRepository } from '#repository/PostRepository';
#Injectable()
export class PostService {
constructor(
#InjectRepository(PostRepository)
private postRepo: AbstractPostRepository,
) {}
async findById(id: string) {
const posts = await this.postRepo.findById(id);
......
return posts;
}
}
src/resolver/query/post.ts
import { Args, Query, Resolver } from '#nestjs/graphql';
import { Authorized } from '#lib/auth/authorized';
import { PermissionScope } from '#lib/auth/permissionScope';
import { PostService } from '#service/postService';
#Resolver()
export class PostsResolver {
constructor(private postService: PostService) {}
#PermissionScope()
#Authorized([
PermissionEnum.READ_MANAGEMENT,
])
#Query()
async findPosts() {
return await this.postService.findById(id);
}
}
The unit test for a resolver related this service:
test/unit/resolver/post.spec.ts
import { Test, TestingModule } from '#nestjs/testing';
import { PERMISSION_MANAGER } from '#lib/auth/permissionManager.module';
import { PostsResolver } from '#resolver/query/post';
import { PostService } from '#service/postService';
describe('PostsResolver', () => {
let resolver: PostsResolver;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
PostsResolver,
{
provide: PERMISSION_MANAGER,
useValue: jest.fn(),
},
{
provide: PostService,
useFactory: () => ({
findById: jest.fn(() => [
{
id: '11111111-1111-1111-1111-111111111111',
name: 'name1',
},
]),
}),
},
],
}).compile();
resolver = module.get<PostsResolver>(PostsResolver);
});
describe('findPosts', () => {
it('should return data', async () => {
const posts = await resolver.findPosts({
id: '11111111-1111-1111-1111-111111111111',
});
const expected = [
{
id: '11111111-1111-1111-1111-111111111111',
name: 'name1',
},
];
expect(posts).toEqual(expected);
});
});
});
When run this test got error:
● PostsResolver › findPosts › should return data
TypeError: Cannot read properties of undefined (reading 'findById')
22 | { id }: FindPostsInput,
23 | ) {
> 24 | return await this.postService.findById(
| ^
25 | id,
26 | );
at PostsResolver.findPosts (src/resolver/query/post.ts:24:41)
at Object.<anonymous> (test/unit/resolver/post.spec.ts:59:42)
It seems the mock service findById in the Test.createTestingModule doesn't work. How to mock correctly? Is it related some inject reasons?

Mock GRPC Clients in nestjs using jest

import { Injectable, Logger, OnModuleInit } from '#nestjs/common';
import { Client, ClientGrpc } from '#nestjs/microservices';
import { catchError, map } from 'rxjs';
import { ICmdUserUsecase } from 'src/adaptor/usecase/ICmdUserUsecase';
import { dataServiceGrpcOptions } from 'src/app/data.options';
import { ICmdRepo } from 'src/adaptor/repo/ICmdRepo';
#Injectable()
export class CmdUserUsecase implements ICmdUserUsecase, OnModuleInit {
private dataCmdRepo: ICmdRepo;
constructor(private readonly logger: Logger) {}
#Client({
...dataServiceGrpcOptions,
})
dataServiceClientGrpc: ClientGrpc;
onModuleInit() {
this.dataCmdRepo = this.dataServiceClientGrpc.getService<ICmdRepo>('DataService');
}
async createUserProfile(data: any) {
return new Promise((resolve, reject) => {
const userData = this.dataCmdRepo.createUser(data).pipe(
catchError((err) => {
if (err.code === 2) {
err.message = 'Data Server is down';
throw new Error(err.message);
} else {
throw new Error(err.message);
}
}),
map((results) => {
return results;
}),
);
userData.subscribe(
(rate) => {
resolve(rate);
},
(error) => {
reject(error);
},
);
});
}
async createUser(data: any): Promise<any> {
return await this.createUserProfile(data)
.then((res) => {
this.logger.log(res);
return res;
})
.catch((err) => {
return err;
});
}
}
here is the client service code which is utilizing the grpc services, every time I am getting connection not found from my spec file,
how can I mock this foresaid grpc service in spec files.
import { INestApplication, Logger } from '#nestjs/common';
import { ConfigModule } from '#nestjs/config';
import { ClientsModule } from '#nestjs/microservices';
import { Test, TestingModule } from '#nestjs/testing';
import { ICmdUserUsecase } from 'src/adaptor/usecase/ICmdUserUsecase';
import { IQueryUserUsecase } from 'src/adaptor/usecase/IQueryUserUsecase';
import { userServiceGrpcOptions } from 'src/app/data.options';
import { configuration } from 'src/utils/configuration';
import { Mock } from 'src/utils/Mocks/mock';
import { MetricsTelemetryModule } from 'telemetry-lib';
import { QueryUserUsecase } from '../query-user-usecase/query.user.usecase';
import { CmdUserUsecase } from './cmd.user.usecase';
describe('CMD user usecase ', () => {
let app: INestApplication;
let cmdUserUsecase: CmdUserUsecase;
beforeEach(async () => {
const moduleRef: TestingModule = await Test.createTestingModule({
imports: [
ConfigModule.forRoot({
load: [configuration],
isGlobal: true,
cache: true,
}),
MetricsTelemetryModule.forRoot({
apiMetrics: true,
}),
ClientsModule.register([
{
name: 'USER_SERVICE',
...userServiceGrpcOptions,
},
]),
],
providers: [
CmdUserUsecase,
{
provide: ICmdUserUsecase,
useClass: CmdUserUsecase,
},
{
provide: IQueryUserUsecase,
useClass: QueryUserUsecase,
},
{
provide: Logger,
useValue: {
log: jest.fn((data) => data),
},
},
],
exports: [],
}).compile();
app = moduleRef.createNestApplication();
await app.init();
cmdUserUsecase = moduleRef.get<CmdUserUsecase>(CmdUserUsecase);
});
afterAll(async () => {
await app.close();
});
describe('root', () => {
it('CmdUserUsecase should be defined', () => {
expect(cmdUserUsecase).toBeDefined();
});
it('CmdUserUsecase"s createUser should be called when invoked', async () => {
try {
await cmdUserUsecase.createUser(Mock.userMock);
expect(cmdUserUsecase.createUser).toHaveBeenCalled();
} catch (error) {
expect(error).toEqual(error);
}
});
it('CmdUserUsecase"s createUser should RETURN suceess message', async () => {
try {
const result = await cmdUserUsecase.createUser(Mock.userMock);
expect(result.status).toBe('success');
} catch (error) {
expect(error).toEqual(error);
}
});
it('CmdUserUsecase"s createUserProfile should be called when invoked', async () => {
try {
await cmdUserUsecase.createUserProfile(Mock.userMock);
expect(cmdUserUsecase.createUserProfile).toHaveBeenCalled();
} catch (error) {
expect(error).toEqual(error);
}
});
it('CmdUserUsecase"s createUserProfile should RETURN suceess message', async () => {
try {
const result = await cmdUserUsecase.createUserProfile(Mock.userMock);
expect(result).toBe('success');
} catch (error) {
expect(error).toEqual(error);
}
});
});
});
How can I modify the above spec file for so that it can contain the mock of the grpc clients as mentioned in the above code.
So after reading a lot of articles I found 2 ways to mock GRPC and use it in the client calls.
Use GRPC-MOCK npm package,
Create a Grpc mock server for the given spec file and add the services at run time. Like
import * as grpc from '#grpc/grpc-js';
import * as protoLoader from '#grpc/proto-loader';
import { INestApplication, Logger } from '#nestjs/common';
import { ConfigModule } from '#nestjs/config';
import { Test, TestingModule } from '#nestjs/testing';
import { IHandlebarJs } from 'src/adaptor/handlebarjs/IHandlebarJs';
import { IMatrixQueryRepo } from 'src/adaptor/repo/IMatrixQueryRepo';
import { Handlebars } from 'src/helper/HandlebarsJs';
import { MatrixQueryRepo } from 'src/infrastructure/repository/MatrixQueryRepo';
import { configuration } from 'src/utils/configuration';
import { Mock } from 'src/utils/mock';
import { QueryMatrixUsecase } from './matrix.service';
const packageDef = protoLoader.loadSync('src/app/proto/as.proto', {});
const grpcObject = grpc.loadPackageDefinition(packageDef);
const asdata: any = grpcObject.asdata;
const server = new grpc.Server();
server.bindAsync(process.env.AS_DATA_SERVICE_URL, grpc.ServerCredentials.createInsecure(), (e, r) => {
console.log(e, r);
server.start();
});
server.addService(asdata.DataService.service, {
SaveAddressGeocode: (call, callback) => {
console.log(call.request);
callback(null, Mock.dsMockResponse);
},
GetAddressGeocode: (call, callback) => {
console.log(call.request);
callback(null, Mock.dsMockResponse);
},
SaveMatrixDistanceAndETA: (call, callback) => {
console.log(call.request);
callback(null, Mock.dsMockResponse);
},
GetMatrixDistanceAndETA: (call, callback) => {
console.log(call.request);
callback(null, Mock.dsMockResponse);
},
});
describe('QueryMatrixUsecase', () => {
let service: QueryMatrixUsecase;
let app: INestApplication;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
imports: [
ConfigModule.forRoot({
load: [configuration],
isGlobal: true,
cache: true,
}),
],
providers: [
QueryMatrixUsecase,
Logger,
{
provide: IMatrixQueryRepo,
useClass: MatrixQueryRepo,
},
{
provide: IHandlebarJs,
useClass: Handlebars,
},
],
}).compile();
app = module.createNestApplication();
await app.init();
service = module.get<QueryMatrixUsecase>(QueryMatrixUsecase);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
it('QueryMatrixUsecase GetRouteMatrix should return a object with status as success', async () => {
const res = await service.GetRouteMatrix(Mock.routeDTOMock);
expect(res.success).toBe('true');
});
});

How to pass Unit test after implementing ngx-bootstrap/datepicker?

I created independent component with ngx-bootstrap/datepicker on angular-cli project.
Everything works fine but Unit test is failing.
But I am new on Unit Testing, and I tried to test but it saying fails.
Here is Travic-CI build log.
https://travis-ci.org/webcat12345/webcat-black-page/builds/221961698
Here is my project version and code.
#angular/cli: 1.0.0
node: 7.6.0
os: linux x64
#angular/cli: 1.0.0
#angular/common: 4.0.2
#angular/compiler: 4.0.2
#angular/compiler-cli: 4.0.2
#angular/core: 4.0.2
#angular/forms: 4.0.2
#angular/http: 4.0.2
#angular/platform-browser: 4.0.2
#angular/platform-browser-dynamic: 4.0.2
#angular/router: 4.0.2
Template
<datepicker class="well well-sm main-calendar" [(ngModel)]="dt" [minDate]="minDate" [showWeeks]="false" [dateDisabled]="dateDisabled"></datepicker>
Component (sorry for posting full code. it is just sample code from ngx-bootstrap demo)
import { Component, OnInit } from '#angular/core';
import * as moment from 'moment';
#Component({
selector: 'app-sidebar-datepicker',
templateUrl: './sidebar-datepicker.component.html',
styleUrls: ['./sidebar-datepicker.component.scss']
})
export class SidebarDatepickerComponent implements OnInit {
public dt: Date = new Date();
public minDate: Date = void 0;
public events: any[];
public tomorrow: Date;
public afterTomorrow: Date;
public dateDisabled: {date: Date, mode: string}[];
public formats: string[] = ['DD-MM-YYYY', 'YYYY/MM/DD', 'DD.MM.YYYY',
'shortDate'];
public format: string = this.formats[0];
public dateOptions: any = {
formatYear: 'YY',
startingDay: 1
};
private opened: boolean = false;
constructor() {
(this.tomorrow = new Date()).setDate(this.tomorrow.getDate() + 1);
(this.afterTomorrow = new Date()).setDate(this.tomorrow.getDate() + 2);
(this.minDate = new Date()).setDate(this.minDate.getDate() - 1000);
(this.dateDisabled = []);
this.events = [
{date: this.tomorrow, status: 'full'},
{date: this.afterTomorrow, status: 'partially'}
];
}
ngOnInit() {
}
public getDate(): number {
return this.dt && this.dt.getTime() || new Date().getTime();
}
public today(): void {
this.dt = new Date();
}
public d20090824(): void {
this.dt = moment('2009-08-24', 'YYYY-MM-DD')
.toDate();
}
public disableTomorrow(): void {
this.dateDisabled = [{date: this.tomorrow, mode: 'day'}];
}
// todo: implement custom class cases
public getDayClass(date: any, mode: string): string {
if (mode === 'day') {
let dayToCheck = new Date(date).setHours(0, 0, 0, 0);
for (let event of this.events) {
let currentDay = new Date(event.date).setHours(0, 0, 0, 0);
if (dayToCheck === currentDay) {
return event.status;
}
}
}
return '';
}
public disabled(date: Date, mode: string): boolean {
return ( mode === 'day' && ( date.getDay() === 0 || date.getDay() === 6 ) );
}
public open(): void {
this.opened = !this.opened;
}
public clear(): void {
this.dt = void 0;
this.dateDisabled = undefined;
}
public toggleMin(): void {
this.dt = new Date(this.minDate.valueOf());
}
}
Test Code
import { async, ComponentFixture, TestBed } from '#angular/core/testing';
import { CUSTOM_ELEMENTS_SCHEMA } from '#angular/core';
import { DatepickerModule } from 'ngx-bootstrap/datepicker';
import { SidebarDatepickerComponent } from './sidebar-datepicker.component';
describe('SidebarDatepickerComponent', () => {
let component: SidebarDatepickerComponent;
let fixture: ComponentFixture<SidebarDatepickerComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ SidebarDatepickerComponent ],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
imports: [DatepickerModule.forRoot()]
})
.compileComponents();
}));
beforeEach(async() => {
fixture = TestBed.createComponent(SidebarDatepickerComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
Please help me to figure out this issue.
Thank you!
1) Use NO_ERRORS_SCHEMA instead of CUSTOM_ELEMENTS_SCHEMA because:
CUSTOM_ELEMENTS_SCHEMA will allow:
any non-Angular elements with a - in their name,
any properties on elements with a - in their name which is the common rule for custom
but your component without -(datepicker)
NO_ERRORS_SCHEMA will allow any property on any element
TestBed.configureTestingModule({
declarations: [ SidebarDatepickerComponent ],
schemas: [NO_ERRORS_SCHEMA],
imports: [DatepickerModule.forRoot()]
})
2) Another option is importing FormsModule
TestBed.configureTestingModule({
declarations: [ SidebarDatepickerComponent ],
imports: [DatepickerModule.forRoot(), FormsModule]
})

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