I need to download the translation file from a remote server and to save it in local to not download this one each time the app is reloading.
The file is downloaded but i can't save it.
import { Storage } from '#ionic/storage';
...
constructor(
private http: HttpClient,
private storage: Storage
) {
}
getTranslation(lang: string): Observable<any> {
return new Observable((observer) => {
this.http.post(SERVER_BASE_URL, null, {headers: this.contentHeader}).subscribe((res: Response) => {
console.log('get translation from server');
console.log(res);
this.storage.set("test", res).then(response => {
console.log("save translation");
}).catch(error => {
console.log("error");
console.log(error);
})
observer.next(res);
observer.complete();
},
error => {
console.log('get translation from local');
// failed to retrieve from api, switch to local
this.http.get('/assets/i18n/' + lang + '.json').subscribe((res: Response) => {
observer.next(res);
observer.complete();
});
});
});
}
I have tried to use Storage but, i have the error
"Cannot read property 'set' of undefined"
I have use the storage in other part of my app and it's work. So I don't understand why in the translationService it's not working.
Thanks for your help.
if you want to store object or list then
this.storage.set('test', JSON.stringify(this.res));
while fetch
this.storage.get('test').then(value => {
let res = JSON.parse(value);
}).catch(err=>{
console.log(err)
})
if you want to save the file then
https://stackoverflow.com/a/57497397/7456041
I have try to save the file in local, i have the same error: Cannot read property 'writeFile' of undefined.
this.http.post(apiAddress, body, {headers: this.contentHeader}).subscribe((res: Response) => {
console.log('get translation from server');
console.log(res);
this.file.writeFile(
this.file.dataDirectory,
lang + '.json',
JSON.stringify(res),
{replace: true}).then(_ => {
console.log('Directory exists');
}).catch(err => {
console.log('Directory doesn\'t exist');
});
observer.next(res);
observer.complete();
},
error => {
console.log('get translation from local');
// failed to retrieve from api, switch to local
this.http.get('/assets/i18n/' + lang + '.json').subscribe((res: Response) => {
observer.next(res);
observer.complete();
});
});
I found what i have missed. In app.module.ts, i need to add "deps" to use the dependencies...
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
// useFactory: (createTranslateLoader),
useClass: TranslationService,
deps: [HttpClient, File]
}
}),
Thanks for your help.
Related
Please, could you help me?
I want to add Sign in with ionic 4 but no documentation I found only this https://www.npmjs.com/package/cordova-plugin-sign-in-with-apple but somehow I couldn't use.
Many Thanks
import { SignInWithApple, AppleSignInResponse, AppleSignInErrorResponse, ASAuthorizationAppleIDRequest } from '#ionic-native/sign-in-with-apple/ngx';
constructor(private signInWithApple: SignInWithApple) { }
this.signInWithApple.signin({
requestedScopes: [
ASAuthorizationAppleIDRequest.ASAuthorizationScopeFullName,
ASAuthorizationAppleIDRequest.ASAuthorizationScopeEmail
]
})
.then((res: AppleSignInResponse) => {
// https://developer.apple.com/documentation/signinwithapplerestapi/verifying_a_user
alert('Send token to apple for verification: ' + res.identityToken);
console.log(res);
})
.catch((error: AppleSignInErrorResponse) => {
alert(error.code + ' ' + error.localizedDescription);
console.error(error);
});
Example if you are also using Firebase
Install native plugin
npm i --save #ionic-native/sign-in-with-apple
In your application
import {
SignInWithApple,
AppleSignInResponse,
AppleSignInErrorResponse,
ASAuthorizationAppleIDRequest
} from '#ionic-native/sign-in-with-apple';
constructor(private afAuth: AngularFireAuth) {}
async nativeAppleAuth(): Promise<void> {
try {
const appleCredential: AppleSignInResponse = await SignInWithApple.signin({
requestedScopes: [
ASAuthorizationAppleIDRequest.ASAuthorizationScopeFullName,
ASAuthorizationAppleIDRequest.ASAuthorizationScopeEmail
]
});
const credential = new firebase.auth.OAuthProvider('apple.com').credential(
appleCredential.identityToken
);
const response = await this.afAuth.auth.signInWithCredential(credential);
console.log('Login successful', response);
} catch (error) {
console.log(error);
}
}
I am able to add an interceptor for the Axios pipeline. Also, I need the loader to be conditional based. The situation is some requests can run in the background and don't need a loader to be blocking the UI. In such cases, I will be able to let the Axios know by sending an extra parameter saying isBackground call. How can I achieve this?
axios.interceptors.request.use((config) => {
this.isLoading = true; // Or trigger start loader
return config
}, (error) => {
this.isLoading = false // Or trigger stoploader
return Promise.reject(error)
})
axios.interceptors.response.use((response) => {
this.isLoading = false // Or trigger stoploader
return response
}, function(error) {
this.isLoading = false // Or trigger stoploader
return Promise.reject(error)
})
Just use your own custom property isBackground on the config like this:
axios.interceptors.request.use((config) => {
console.log(config.isBackground)
return config
}, (error) => {
console.log(error.config.isBackground)
return Promise.reject(error)
})
axios.interceptors.response.use((response) => {
console.log(response.config.isBackground)
return response
}, function(error) {
console.log(error.config.isBackground)
return Promise.reject(error)
})
const config = {
isBackground: true
}
axios.get('https://httpbin.org/get', config)
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error)
})
Note that there is a bug in current release 0.19.0 waiting to be fixed, which breaks this functionality. Works ok in version 0.18...
Fiddle
I am trying to upload an image using formData. The api is working fine. But the data is displaying null in the server.
My function is
capture_dl_front(){
this.camera.getPicture(this.cameraOptions)
.then(imageData => {
this.customer.dl_front = normalizeURL(imageData);
this.upload_dl_front(imageData);
}, error => {
this.func.showAlert('Error',JSON.stringify(error));
});
}
upload_dl_front(imageFileUri: any): void {
this.file.resolveLocalFilesystemUrl(imageFileUri)
.then(entry => (<FileEntry>entry).file(file => this.readFile_dl_front(file)))
.catch(err => console.log('Error',JSON.stringify(err)));
}
private readFile_dl_front(file: any) {
const reader = new FileReader();
reader.onloadend = () => {
const imgBlob = new Blob([reader.result], { type: file.type });
this.dl_front_imageUri = imgBlob;
this.dl_front_imageName = file.name;
alert(this.dl_front_imageName)
const img = new FormData();
img.append('image', this.dl_front_imageUri, this.dl_front_imageName)
this.api.test(img).then(data=>alert("final: "+data))
};
reader.readAsArrayBuffer(file);
}
and my api function is
test(image){
let headers = new HttpHeaders({
'Content-Type': 'application/x-www-form-urlencoded',
});
return new Promise( resolve => {
this.http.post(url, image, { headers: headers})
.subscribe(
data => {
resolve(data['message']);
},
error => {
resolve(error.statusText);
}
);
});
}
and i am getting the file in my laravel server as
$image = $request->file('image');
but i am getting null in the image parameter.
What am i doing wrong here?
You should remove the headers in the api call.
test(image){
return new Promise( resolve => {
this.http.post(url, image)
.subscribe(
data => {
resolve(data['message']);
},
error => {
resolve(error.statusText);
}
);
});
}
I'm trying to make an introduction page that will read a QR Code, save the code and pass to another page. This will occur only the first time you open the application. When closing the app and reopen, the introduction page should not appear. So, what is my problem? I'm saving the code I read, but when I close the app and open again, the code that I had saved was lost and the introduction page appears. How do I solve this?
My IntroPage code is:
import { NativeStorage } from '#ionic-native/native-storage';
const STORAGE_KEY = 'hospitals';
...
scannedCode:string = null;
constructor(private navCtrl: NavController,
private barcodeScanner: BarcodeScanner,
private nativeStorage: NativeStorage,
private toast: Toast) {}
public scanCode() {
this.barcodeScanner.scan().then(barcodeData => {
this.scannedCode = barcodeData.text;
if (this.scannedCode === "123"){
this.save(this.scannedCode);
this.navCtrl.push(LoginPage);
}
else{
this.makeToastMessage('Invalid Hospital!', '5000', 'bottom');
}
}, (err) => {
console.log('Error: ', err);
});
};
private save(val){
console.log('data added ' + val);
this.nativeStorage.setItem(STORAGE_KEY, {property: val})
.then(
() => console.log('Stored item!'),
error => this.makeToastMessage('Error storing item', '5000', 'center')
);
};
And my app.component.ts code is:
import { NativeStorage } from "#ionic-native/native-storage";
const STORAGE_KEY = 'hospitals';
...
rootPage:any;
constructor(platform: Platform, statusBar: StatusBar,
splashScreen: SplashScreen, public push: Push,
public alertCtrl: AlertController,
private nativeStorage: NativeStorage) {
platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
statusBar.styleDefault();
splashScreen.hide();
this.pushsetup();
this.setRootPage();
});
}
private setRootPage(){
let localStorage:string = "Not got";
this.nativeStorage.getItem(STORAGE_KEY)
.then(
item => localStorage = item.properity,
error => console.log("Error getting item. Error: " + error)
);
alert(localStorage);
switch (localStorage){
case "123":
this.rootPage = LoginPage;
break;
default:
this.rootPage = IntroPage;
break;
}
}
It is not lost. You are checking the value outside your promise then function so it might be executed before data is fetched.
You need to either use the switch case within then where you are looking for the data or chain the promises.
private setRootPage(){
let localStorage:string = "Not got";
this.nativeStorage.getItem(STORAGE_KEY)
.then(
item => localStorage = item.properity,
error => console.log("Error getting item. Error: " + error)
).then(_=>{
switch (localStorage){
case "123":
this.rootPage = LoginPage;
break;
default:
this.rootPage = IntroPage;
break;
}
});
}
This will ensure you will check the value only after the value is fetched from the storage.
Or in short:
private setRootPage(){
this.nativeStorage.getItem(STORAGE_KEY)
.then(
item => {
switch (item.property){
case "123":
this.rootPage = LoginPage;
break;
default:
this.rootPage = IntroPage;
break;
}
},
error => console.log("Error getting item. Error: " + error)
)
}
Meteor.methods({
'sync.toggl'(apiToken) {
const toggl = new TogglApi({ apiToken });
Promise.promisifyAll(toggl);
toggl.getWorkspacesAsync()
.each(ws => toggl.getWorkspaceProjectsAsync(ws.id)
.map(p => {
Projects.upsert({ projectId: p.id }, {
projectId: p.id,
name: p.name,
tracker: 'toggl',
tags: [],
contributors: []
});
})
.catch(err => console.error(`fetching ${ws.name} projects error - ${err.message}`));
)
.catch(err => console.error(`fetching ${ws.name} workspace error - ${err.message}`));
}});
I'm trying to save data from toggl api into local db here. But Meteor throws an error - Meteor code must always run within a Fiber. Try wrapping callbacks that you pass to non-Meteor libraries with Meteor.bindEnvironment. I found couple solutions, but they doesn't allow me to use bluebird promises... or not?
Using async/await worked for me:
Meteor.methods({
'sync.toggl'(apiToken) {
const toggl = new TogglApi({ apiToken });
Promise.promisifyAll(toggl);
async function saveProject(pid, name) {
try {
return await Projects.upsert(
{ pid },
{
pid,
name,
tracker: 'toggl',
contributors: [],
}
)
} catch (err) {
return console.error(`async saveProject failed - ${err.message}`);
}
}
toggl.getWorkspacesAsync()
.each(ws => toggl.getWorkspaceProjectsAsync(ws.id)
.map(p => {
saveProject(p.id, p.name);
})
.catch(err => console.error(`fetching projects error - ${err.message}`))
)
.catch(err => console.error(`fetching workspaces error - ${err.message}`))
}});