HELP :Ionic /i'm trying to upload files to firebase but i can't read the content of the file help enter image description here
import { Component } from '#angular/core';
import { File} from '#ionic-native/file/ngx';
import { FileChooser } from '#ionic-native/file-chooser/ngx';
import { FilePath } from '#ionic-native/file-path/ngx';
import { FireBaseService } from 'src/app/services/firebase-service.service';
import { Plugins, FilesystemDirectory, FilesystemEncoding } from '#capacitor/core';
const { Filesystem } = Plugins;
#Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage {
fileforSending ;
fileUri :string;
filePath :string;
fileName :string;
fileType :string;
entry;
constructor(
private fireService:FireBaseService,
private fileChooser:FileChooser,
private file :File,
private pathConverter :FilePath) {
}
choose(){
this.fileChooser.open()
.then(uri => {
//getting URI of a choosen file
this.fileUri = uri;
return this.file.resolveLocalFilesystemUrl(this.fileUri);
}).then(fileEntry => {
this.entry = fileEntry;
this.entry.file((arg) => {
//getting mime type of a file
this.fileType = arg.type;
})
}).then(() => {
return this.pathConverter.resolveNativePath(this.fileUri)
}).then((filePath) => {
//converting file URI to normal file PATH & file NAME
this.filePath = filePath.substring(0, filePath.lastIndexOf('/'));
this.fileName = filePath.substring(filePath.lastIndexOf('/'), filePath.length).replace("/", "");
}).then(async () => {
try {
const buffer = await this.file.readAsArrayBuffer(this.filePath, this.fileName);
await this.fireService.uploadFileToStorage(buffer, this.fileType, this.fileName);
} catch (error) {
alert(`Buffering failed ${JSON.stringify(error)}`)
} finally {
alert('finally');
}
}).catch(err => {console.log('error: ', err) });
}
}
<!-- begin snippet: js hide: false console: true babel: false -->
--------------------------firebase service-----------------------
import { Injectable } from '#angular/core';
import {AngularFireStorage} from "#angular/fire/storage";
#Injectable({
providedIn: 'root'
})
export class FireBaseService {
constructor(private af: AngularFireStorage){}
async uploadFileToStorage(file, type, name) {
const randomId = Math.random()
.toString(36)
.substring(2, 8);
let oMyBlob = new Blob([file], {type : type})
const uploadTask = this.af.upload(`files/${new Date().getTime()}_${randomId}_${name}`,oMyBlob);
console.log('upload task '+uploadTask)
uploadTask.then(async res => {
console.log('file upload finished!');
}).catch(err => {
console.log('file wasnt upload. Error: ' + err);
});
}
}
export { FireBaseService as ExportedClass };
import { Injectable } from '#angular/core';
import {AngularFireDatabase} from "#angular/fire/database";
import {AngularFireStorage} from "#angular/fire/storage";
#Injectable({
providedIn: 'root'
})
export class FireBaseService {
constructor(private af: AngularFireStorage){}
async uploadFileToStorage(file, type, name) {
const randomId = Math.random()
.toString(36)
.substring(2, 8);
let oMyBlob = new Blob([file], {type : type})
const uploadTask = this.af.upload(
`files/${new Date().getTime()}_${randomId}_${name}`,
oMyBlob
);
uploadTask.then(async res => {
console.log('file upload finished!');
}).catch(err => {
console.log('file wasnt upload. Error: ' + err);
});
}
}
export { FireBaseService as ExportedClass };
Related
I'm working with NestJS with GraphQL and MongoDB.
I'm trying store image files using GridFS using mongo-gridfs package.
Uploading images to database works fine, but how can I access to this files?
I mean for example I want to get source path of this files and use it in my frontend
Here is my resolver and service:
// photo.resolver.ts
import { Resolver, Mutation, Query, Args } from '#nestjs/graphql';
import { GraphQLUpload, FileUpload } from 'graphql-upload';
import { Photo } from './dto/photo.dto';
import { PhotoService } from './services/photo.service';
#Resolver()
export class PhotoResolver {
constructor(
private readonly photoService: PhotoService
) {}
#Query(() => ???, { nullable: true })
async photo(#Args('id', { nullable: true }) id: string) {
const photo = await this.photoService.findOne(id);
return ???;
}
#Mutation(() => Photo)
async uploadPhoto(#Args({name: 'file', type: () => GraphQLUpload}) file: FileUpload) {
return await this.photoService.save(file);
}
}
// photo.service.ts
import { Connection } from 'mongoose';
import { Injectable } from '#nestjs/common';
import { InjectConnection } from '#nestjs/mongoose';
import { FileUpload } from 'graphql-upload';
import { MongoGridFS } from 'mongo-gridfs';
import { Photo } from '../photo.interface';
#Injectable()
export class PhotoService {
private fileModel: MongoGridFS;
constructor(
#InjectConnection() private readonly connection: Connection
) {
this.fileModel = new MongoGridFS(this.connection.db as any, 'photo');
}
async findOne(id: string) {
return await this.fileModel.findById(id);
}
async save(file: FileUpload): Promise<Photo> {
return await this.fileModel.writeFileStream(file.createReadStream(), {
filename: file.filename,
contentType: file.mimetype
});
}
}
I've tried two approached:
I used downloadFile method from my photoModel, but it returns path to this file in my Temp directory in local disk.
// photo.service.ts
async findOne(id: string): Promise<string> {
return await this.fileModel.downloadFile(id); // C:\...\AppData\Local\Temp\189450ef
}
// photo.resolver.ts
#Query(() => String, { nullable: true })
async photo(#Args('id', { nullable: true }) id: string) {
return id && await this.photoService.findOne(id);
}
It works per se but it doesn't look to me as a proper solution. I'd prefer that source path should "lead" to my server.
I used readFileStream method from my photoModel, which return filestream and added #Res() res to arguments in resolver.
// photo.service.ts
async findOne(id: string): Promise<GridFSBucketReadStream> {
return await this.fileModel.readFileStream(id);
}
// photo.resolver.ts
#Query(() => Boolean)
async photo(#Args('id', { nullable: true }) id: string, #Res() res) {
const photoStream = await this.photoService.findOne(id);
photoStream.pipe(res);
return true;
}
And now I've got such an error in terminal:
[Nest] 12408 - 10.07.2021, 13:02:25 [ExceptionsHandler] dest.on is not a function +27555ms
TypeError: dest.on is not a function
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
I am trying to use #waves/waves-crypto I have import * as wavesCrypto from '#waves/waves-crypto' in my .ts file but I am still getting error within the npm module itself. I am trying to create a waves wallet using nativescript and right now I am trying to create the address and seed and public and private key for the user. this is login.ts where im calling the #waves/waves-crypto
import { Component, ElementRef, ViewChild } from "#angular/core";
import { Router } from "#angular/router";
import { alert, prompt } from "tns-core-modules/ui/dialogs";
import { Page } from "tns-core-modules/ui/page";
import { Routes } from "#angular/router";
//import { publicKey, verifySignature, signBytes, address, keyPair, privateKey } from "../#waves/waves-crypto";
import * as wavesCrypto from '../#waves/waves-crypto';
import { User } from "../shared/user.model";
import { UserService } from "../shared/user.service";
#Component({
selector: "app-login",
moduleId: module.id,
templateUrl: "./login.component.html",
styleUrls: ['./login.component.css']
})
export class LoginComponent {
isLoggingIn = true;
user: User;
#ViewChild("password") password: ElementRef;
#ViewChild("confirmPassword") confirmPassword: ElementRef;
#ViewChild("waves") waves: ElementRef;
constructor(private page: Page, private userService: UserService, private router: Router) {
this.page.actionBarHidden = true;
this.user = new User();
// this.user.email = "foo2#foo.com";
// this.user.password = "foo";
const seed = 'magicseed';
const pubKey = wavesCrypto.publicKey(seed);
const bytes = Uint8Array.from([1, 2, 3, 4]);
const sig = wavesCrypto.signBytes(bytes, seed);
const isValid = wavesCrypto.verifySignature(pubKey, bytes, sig)
}
wallet() {
let walletAddress = wavesCrypto.address('seed', 'T');
let keyPair = wavesCrypto.keyPair('seed');
//publicKey('seed');
//privateKey('seed');
wavesCrypto.privateKey('seed');
alert(walletAddress);
console.log(walletAddress);
console.log(keyPair);
}
toggleForm() {
this.isLoggingIn = !this.isLoggingIn;
}
submit() {
if (!this.user.email || !this.user.password) {
this.alert("Please provide both an email address and password.");
return;
}
if (this.isLoggingIn) {
this.login();
} else {
this.register();
}
}
login() {
this.userService.login(this.user)
.then(() => {
this.router.navigate(["/home"]);
})
.catch(() => {
this.alert("Unfortunately we could not find your account.");
});
}
register() {
if (this.user.password != this.user.confirmPassword) {
this.alert("Your passwords do not match.");
return;
}
this.userService.register(this.user)
.then(() => {
this.alert("Your account was successfully created.");
this.isLoggingIn = true;
})
.catch(() => {
this.alert("Unfortunately we were unable to create your account.");
});
}
forgotPassword() {
prompt({
title: "Forgot Password",
message: "Enter the email address you used to register for APP NAME to reset your password.",
inputType: "email",
defaultText: "",
okButtonText: "Ok",
cancelButtonText: "Cancel"
}).then((data) => {
if (data.result) {
this.userService.resetPassword(data.text.trim())
.then(() => {
this.alert("Your password was successfully reset. Please check your email for instructions on choosing a new password.");
}).catch(() => {
this.alert("Unfortunately, an error occurred resetting your password.");
});
}
});
}
focusPassword() {
this.password.nativeElement.focus();
}
focusConfirmPassword() {
if (!this.isLoggingIn) {
this.confirmPassword.nativeElement.focus();
}
}
alert(message: string) {
return alert({
title: "APP NAME",
okButtonText: "OK",
message: message
});
}
}
I have the same problem and I opened the next issue on the Github repo (you can go and click like or comment), link here
In the issue I explain a workaround that is working for me to validate a signature, you can use the same snippet.
First import manually the submodules needed:
import { default as axlsign } from '#waves/signature-generator/libs/axlsign';
import { default as convert } from '#waves/signature-generator/dist/utils/convert';
import { concatUint8Arrays } from '#waves/signature-generator/dist/utils/concat';
import { default as base58 } from '#waves/signature-generator/dist/libs/base58';
Then you can use the next code to validate the signature and publickey:
let prefix = "WavesWalletAuthentication";
let host = new URL(yourServerUrl).hostname;
let user = wavesAddressString;
let payload = theStringThatWasSigned;
let data = [prefix, host, payload]
.map(d => convert.stringToByteArrayWithSize(d))
.map(stringWithSize => Uint8Array.from(stringWithSize));
let dataBytes = concatUint8Arrays(...data);
let publicKeyBytes = base58.decode(publicKeyOnBase58Format);
let signatureBytes = base58.decode(signatureOnBase58Format);
let validSignature = axlsign.verify(publicKeyBytes, dataBytes, signatureBytes);
console.log("(login) validSignature?", validSignature);
I'm setting up a local storage for settings form , and want to set and get each value of that form in local storage of my application. What i need to add to make set and get correctly for this form?
everyone can see that the get results has error and mabe the set is not done correctly.
How to make all of that work
do i need to change set and get methods? is there anythin that i am missing ? i tried all i know but i am a beginner in local storage and ionic .
my file ts :
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.min.js"></script>
import { Component } from '#angular/core';
import { NavController, NavParams } from 'ionic-angular';
import { FormBuilder, FormGroup, Validators, NgForm, FormControl, ValidatorFn, AbstractControl } from '#angular/forms';
import { ToastController } from 'ionic-angular';
import { EspaceAgentPage } from '../espace-agent/espace-agent';
import { EspaceCitoyenPage } from '../espace-citoyen/espace-citoyen';
import { ChangePasswordPage } from '../change-password/change-password';
import { Storage } from '#ionic/storage';
import { PasswordService } from '../services/password.service';
import { NgModule } from '#angular/core';
#Component({
selector: 'page-settings',
templateUrl: 'settings.html',
})
export class SettingsPage {
private Form : FormGroup;
public mail: any;
public tel: any;
public data: any;
constructor(public navCtrl: NavController, public navParams: NavParams, public toastCtrl: ToastController, private formBuilder: FormBuilder, public storage: Storage)
{
this.Form = formBuilder.group({
mailadress: ['', Validators.compose([Validators.pattern('^[a-zA-Z0-9_.+-]+#[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$'),Validators.email])],
telephone: ['', Validators.compose([ Validators.pattern('[0-9]*'), Validators.minLength(8), Validators.maxLength(8)])],
});
}
ionViewDidLoad() {
console.log('ionViewDidLoad SettingsPage');
this.getValue("stoker");
}
// set a key/value
setValue(key: string, value: any)
{
this.storage.set(key, value).then((response) => {
console.log('set' + key + ' ', response);
}).catch((error) => {
console.log('set error for ' + key + ' ', error);
});
}
// get a key/value pair
getValue(key: string) {
this.storage.get(key).then((val) => {
console.log('get ' + key + ' ', val);
this.data[key] = "";
this.data[key] = val;
}).catch((error) => {
console.log('get error for ' + key + '', error);
});
}
onChangepassword()
{
this.navCtrl.push(ChangePasswordPage);
}
onSubmit(form: NgForm)
{
this.mail=this.Form.get('mailadress').value;
this.tel=this.Form.get('telephone').value;
console.log(form.value);
this.setValue("stoker",this.mail);
this.setValue("stoker",this.tel);
this.navCtrl.push(EspaceCitoyenPage);
const toast = this.toastCtrl.create({
message: 'Modifications Enregistrées !',
duration: 4000
});
toast.present();
}
}
console results capture :
capture
it seems that you get the error in this funtion
// get a key/value pair
getValue(key: string) {
this.storage.get(key).then((val) => {
console.log('get ' + key + ' ', val);
this.data[key] = "";
this.data[key] = val;
}).catch((error) => {
console.log('get error for ' + key + '', error);
});
}
when you try to get stoker key returns a null reference and then the error. Maybe there is not item stored for this key or the palform was not ready when you call the storage.
When you work arround the storage you shoud wait from the platform to be ready like this:
import { Platform } from '#ionic/angular';
import { NativeStorage } from '#ionic-native/native-storage/ngx';
-----
constructor(private storage: NativeStorage, private plt: Platform) {}
this.plt.ready().then(() => {
// call native storage
});
And think is better use Native Storage than ionic storage.
Hope this help you.
plsease refer this
import { NativeStorage } from '#ionic-native/native-storage/ngx';
constructor(private nativeStorage: NativeStorage) { }
import { NativeStorage } from '#ionic-native/native-storage/ngx';
constructor(private nativeStorage: NativeStorage) { }
this.nativeStorage.setItem('myitem', {property: 'value', anotherProperty: 'anotherValue'})
.then(
() => console.log('Stored item!'),
error => console.error('Error storing item', error)
);
this.nativeStorage.getItem('myitem')
.then(
data => console.log(data),
error => console.error(error)
);
this.nativeStorage.setItem('myitem', {property: 'value', anotherProperty: 'anotherValue'})
.then(
() => console.log('Stored item!'),
error => console.error('Error storing item', error)
);
this.nativeStorage.getItem('myitem')
.then(
data => console.log(data),
error => console.error(error)
);
localstorage.setitem('your key as your wish',your value),
all storage value are stored in string
ex;-
localstorage.setitem('key', value)
localstorage.getitem('key')
You can use
Windows.localstorage.setitem('key', value)
I am following this tutorial https://www.concretepage.com/angular-2/ngrx/ngrx-entity-example. I have now Firestore as my backend. I can retrieve 'LOAD_ALL_ARTICLES' from Firestore. But my code breaks when I try to listen for the 'ADD' action. Any ideas please?!
import { Injectable } from '#angular/core';
import { Action } from '#ngrx/store';
import { Actions, Effect } from '#ngrx/effects';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/observable/fromPromise';
import 'rxjs/add/operator/mergeMap';
import * as fromActions from '../actions/article.actions';
import * as fromReducer from '../reducers/article.reducer';
//import { ArticleService } from '../services/article.service';
import { Article } from '../models/article';
import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument } from 'angularfire2/firestore';
#Injectable()
export class ArticleEffects {
constructor(
private actions$: Actions,
private afs: AngularFirestore
) {}
#Effect()
loadAllArticles$: Observable<Action> = this.actions$
.ofType(fromActions.ArticleActionTypes.LOAD_ALL_ARTICLES)
.switchMap(() =>
const ref = this.afs.collection<Article>('articles');
return ref.snapshotChanges().map(arr => {
return arr.map(action => {
const data = action.payload.doc.data() as Article;
const id = action.payload.doc.id;
return { id, ...data };
})
})
.map(data => new fromActions.LoadArticlesSuccess({ articles: data }));
//Listen for the 'ADD' action
#Effect()
addArticle$: Observable<Action> = this.actions$
.ofType(fromActions.ArticleActionTypes.ADD_ARTICLE)
.map((action: fromActions.AddArticle) => action.payload)
.switchMap( payload => {
const ref = this.afs.doc<Article>(`articles/${payload.article.id}`);
return Observable.fromPromise(ref.set(payload.article));
})
}
}
I believe you need to switchMap first:
#Effect()
addArticle$: Observable<Action> = this.actions$
.ofType(fromActions.ArticleActionTypes.ADD_ARTICLE)
.switchMap((action: fromActions.AddArticle) => of(action.payload))
.map( payload => {
const ref = this.afs.doc<Article>(`articles/${payload.article.id}`);
return Observable.fromPromise(ref.set(payload.article));
})