How to write data into csv file from ionic form? - ionic-framework

I am newbie to Ionic.
I have two fields in the form
<ion-item>
<ion-label floating>Name</ion-label>
<ion-input #name type="text"></ion-input>
</ion-item>
<ion-item>
<ion-label floating>school</ion-label>
<ion-input #school type="text"></ion-input>
</ion-item>
<div padding>
<button block ion-button (click)="SaveForm()">Save data</button>
</div>
After user clicking on the save button, I want to save the data in csv format in local file system.
I tried
SaveForm()
{
var finalCSV = this.name.value+','+this.school.value;
alert('finalCSV');
$cordovaFile.writeFile(cordova.file.externalRootDirectory, 'data.csv', finalCSV, true).then(function(result){
alert('Success! Export created!');
}, function(err) {
console.log("ERROR");
})
}
In the same ts file I have added
import {File} from 'ionic-native';
declare var cordova:any;
const fs:string = cordova.file.dataDirectory;
File.checkDir(this.fs, 'mydir')
.then(_ => console.log('yay'))
.catch(err => console.log('boooh'));
I am getting following Error
Typescript Error Cannot find name '$cordovaFile'.
How to resolve this Error?
Is there any better approach to implement this?

import {Page, Platform} from 'ionic/ionic';
constructor(platform: Platform) {
this.platform = platform;
}
this.platform.ready().then(() => {
cordovaFile.writeFile(cordova.file.externalRootDirectory, 'data.csv', finalCSV, true).then(function(result){
alert('Success! Export created!');
}, function(err) {
console.log("ERROR");
})
}

Related

Login using API in Ionic 6

## login.page.ts ##
import { Component, OnInit } from '#angular/core';
import { AuthService } from 'src/services/auth/auth.service';
import { NavController } from '#ionic/angular';
import { AlertService } from 'src/services/alert/alert.service';
import { NgForm } from '#angular/forms';
#Component({
selector: 'app-login',
templateUrl: './login.page.html',
styleUrls: ['./login.page.scss']
})
export class LoginPage implements OnInit {
constructor(
private authService: AuthService,
private navCtrl: NavController,
private alertService: AlertService
) { }
ngOnInit() {
}
onLogin(form: NgForm) {
this.authService.login(form.value.username, form.value.password).subscribe(
() => {
this.alertService.presentToast("Logged In");
this.navCtrl.navigateRoot('/welcome');
},
error => {
console.log(error);
},
() => {
this.alertService.presentToast("Failed");
this.navCtrl.navigateRoot('/login');
}
);
}
}
## login.page.scss ##
ion-content.background{
--background: url(../../assets/img/staffandtruck.jpg) 0 0/100% 100% no-repeat;
}
## login.page.html ##
<ion-content padding class="background">
<ion-card>
<img src="assets/img/logo2.png"/>
</ion-card>
<ion-card>
<ion-card-content>
<form #form="ngForm" (ngSubmit)="onLogin(form)">
<ion-item>
<ion-icon slot="start" name="person-circle"></ion-icon>
<ion-label position="floating">Staff ID</ion-label>
<ion-input type="email" name="username" ngModel required></ion-input>
</ion-item>
<ion-item>
<ion-icon slot="start" name="key"></ion-icon>
<ion-label position="floating">Password</ion-label>
<ion-input type="password" name="password" ngModel required></ion-input>
</ion-item>
<ion-card-content>
<ion-button expand="block" color="primary" type="submit">Log in</ion-button>
</ion-card-content>
</form>
</ion-card-content>
</ion-card>
</ion-content>
i am new here and beginner in Ionic Framework. Is there anyone can help me and teach me on how to create a login using API that call username and password without create a Model for User? I don't know how to startup and implement this API. This is my environment setup for Ionic.
My environment setup for Ionic. This is for environment service that calling API for login EnvService.ts. This is for auth service AuthService.ts. But, that all not functioning as I wish.

Ionic-Vue Ionicons 5.x.x doesn't show icon

I used ionic-vue with ionicons 5.0.1 but after call
<ion-icon name="add"></ion-icon>
i was following https://dev.to/aaronksaunders/build-your-first-ionic-vue-app-18kj and https://github.com/ionic-team/ionic/issues/19078 tutorial, but stucked and icon in FAB cannot be show.
This is my syntax, thank you for helping.
<template>
<ion-page>
....
<ion-fab vertical="bottom" horizontal="end" slot="fixed">
<ion-fab-button #click="$router.push({ name: 'new-item' })">
<ion-icon name="add"></ion-icon>
</ion-fab-button>
</ion-fab>
</ion-content>
</ion-page>
</template>
<script>
...
import { addIcons } from 'ionicons';
import * as allIcons from 'ionicons/icons';
const currentIcons = Object.keys(allIcons).map(i => {
const key = i.replace(/[A-Z]/g, letter => `-${letter.toLowerCase()}`)
if(typeof allIcons[i] === 'string') {
return {
[key]: allIcons[i],
}
}
return {
['ios-' + key]: allIcons[i].ios,
['md-' + key]: allIcons[i].md,
};
});
const iconsObject = Object.assign({}, ...currentIcons);
addIcons(iconsObject);
...
</script>
Result FAB does not show icon 'add':
For Ionic Vue 3 using Composition API:
<template>
<ion-icon :icon="rocket" />
</template>
<script>
import { IonIcon } from '#ionic/vue';
import { rocket } from 'ionicons/icons';
export default {
components: { IonIcon },
setup() {
return {
rocket
}
}
}
</script>
For <script setup>
<script setup>
import { IonIcon } from '#ionic/vue';
import { rocket } from 'ionicons/icons';
</script>
<template>
<ion-icon :icon="rocket" />
</template>
I was also following the same guide(https://dev.to/devmount/how-to-use-ionicons-v5-with-vue-js-53g2), and I encountered the same issue.
I decided to downgrade the ionicons version to version 4:
npm i ionicons#4
This solved my issue.
The code that I used from the guide:
<template>
<ion-page>
<ion-header>
<ion-toolbar color="primary">
<ion-title>Home</ion-title>
</ion-toolbar>
</ion-header>
<ion-content padding>
<ion-list>
<ion-item>
<ion-checkbox slot="start"></ion-checkbox>
<ion-label>
<h1>Create Ideaa</h1>
<ion-note>Run Idea by Brandy</ion-note>
</ion-label>
<ion-badge color="success" slot="end">5 Days</ion-badge>
</ion-item>
</ion-list>
<ion-fab vertical="bottom" horizontal="end" slot="fixed">
<ion-fab-button >
<ion-icon name="add" ></ion-icon>
</ion-fab-button>
</ion-fab>
</ion-content>
</ion-page>
</template>
<script>
import { add } from "ionicons/icons";
import { addIcons } from "ionicons";
addIcons({
"ios-add": add.ios,
"md-add": add.md
});
export default {
name: "HomePage",
props: {
msg: String
}
};
</script>
In your main.js file
import * as allIcons from "ionicons/icons";
Vue.mixin({
data() {
return {
i: allIcons,
};
},
methods: {
icon(name) {
return this.i[name];
}
}
});
now you can use <ion-icon :src="icon('search')"></ion-icon> anywhere in the vue application, it is going to work
hey thanks for checking out the blogs and videos...
you can also get the icons this way...
<template>
<ion-button #click="handleAddItemClicked" >
<ion-icon slot="icon-only" :src="i.saveOutline" ></ion-icon>
</ion-button>
<ion-button #click="handleAddItemClicked" >
<ion-icon slot="icon-only" :src="i.save" ></ion-icon>
</ion-button>
<ion-button #click="handleAddItemClicked" >
<ion-icon slot="icon-only" :src="i.saveSharp" ></ion-icon>
</ion-button>
</template>
<script>
import * as allIcons from "ionicons/icons";
...
data() {
return {
i : allIcons,
};
},
</script>
I followed this comment in a closed issue on #modus/ionic-vue repo: https://github.com/ModusCreateOrg/ionic-vue/issues/120#issuecomment-633666592
import { addIcons } from 'ionicons'
import { add, cartOutline } from 'ionicons/icons'
addIcons({ add, "cart-outline": cartOutline })
This worked with ionicons#5.1.2 installed. Note how the multi word icon imports are camel case instead of kebab case. If you want to use the kebab case variant of the name for an ion-icon you have to do the assignment to the kebab case name yourself like in the case of cart-outline above.
Though if you wanted to add all of them at once and support kebab case, you could map a new object like this:
import { addIcons } from 'ionicons'
import * as allIcons from 'ionicons/icons'
import _ from 'lodash'
addIcons(_.mapKeys(allIcons, (value, key) => _.kebabCase(key))
After i tried everything, there weren't any errors reported anywehere, just icon wasn't there.
Please check twice, that you have set the color of the icon, because in default icon style color is inhereit.
So, if you have for example, a green button, the color of the icon will be also green, if you do not specify.

ion-select, ion-input and retrive its value on second page

I am getting the number values from the ion-select and input a number in the ion-input. How can I display the selected value and the input value from the original page to another page?
I am using ionic 4
<ion-item>
<ion-input #user2 type="tel" maxlength="14" minlength="4" [(ngModel)]="numpad"
name="userCount" (keypress)="numberOnlyValidation($event)"></ion-input>
</ion-item>
<ion-item (click)="openSelect()">
<ion-input [(ngModel)]="selectedCode"></ion-input>
</ion-item>
<ion-item style="display: none">
<ion-select #select1 [(ngModel)]="selectedCode">
</ion-select>
</ion-item>
Here's one solution. Assume the input is in home.page and the values will be routed to page2.page.
Update app-routing.module.ts and add a new route
{
path: 'page2/:code/:numpad',
loadChildren: () => import('./page2/page2.module').then( m => m.Page2PageModule)
},
Then you will want to take the values from home.page and navigate to page 2. There are a few different way to do this. In the example below I'm just using ionChange to call a function to route to page2.
home.page.ts
<ion-item>
<ion-input #user2 type="tel" maxlength="14" minlength="4" [(ngModel)]="numpad" name="userCount"></ion-input>
</ion-item>
<ion-item>
<ion-select [(ngModel)]="selectedCode" (ionChange)="valueChangedSoRouteToPage2()">
<ion-select-option *ngFor="let user of users" [value]="user.id">{{user.first + ' ' + user.last}}</ion-select-option>
</ion-select>
</ion-item>
Then in home.page.ts you can do something like this
valueChangedSoRouteToPage2() {
console.log('changed');
console.log(this.selectedCode);
console.log(this.numpad);
this.router.navigateByUrl('/page2/' + this.selectedCode + '/' + this.numpad);
}
Last step - update page2.page.ts
import { Component, OnInit } from '#angular/core';
import { ActivatedRoute } from '#angular/router';
#Component({
selector: 'app-page2',
templateUrl: './page2.page.html',
styleUrls: ['./page2.page.scss'],
})
export class Page2Page implements OnInit {
page2Code;
page2Numpad;
constructor(private activatedRoute: ActivatedRoute) { }
ngOnInit() {
this.page2Code = this.activatedRoute.snapshot.paramMap.get("code");
this.page2Numpad = this.activatedRoute.snapshot.paramMap.get("numpad");
console.log('code: ' + this.page2Code);
console.log('numpad: ' + this.page2Numpad);
}
}
Hope this helps.

Response with status: 0 for URL: null – getting this error when I run in simulator or web

I am developing a simple mobile maid android based app using Ionic framework and I am using laravel for my backend. I am getting ‘Response with status: 0 for URL: null’ this error when I run it in web or android simulator.
I could not be able to register a new user, when I used POSTMAN to check my restful API it works and I could be a able to register a new user. But when I run this app in simulator it keep on showing this ‘Response with status: 0 for URL: null’ error.
**auth-service.ts file**
import { Injectable } from '#angular/core';
import {Http, Headers} from '#angular/http'
import 'rxjs/add/operator/map';
let apiUrl = 'http://fypBackend.test/api/';
#Injectable({
providedIn: 'root'
})
export class AuthServiceService {
constructor(public http: Http) { }
register(data){
return new Promise((resolve, reject) => {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
this.http.post(apiUrl+'users', JSON.stringify(data), {headers: headers})
.subscribe(res => {
resolve(res.json());
}, (err) => {
console.log('Not Working')
reject(err);
});
});
}
}
**register.ts file**
import { Component} from '#angular/core';
import { NavController,LoadingController, ToastController } from '#ionic/angular';
import {AuthServiceService} from '../auth-service.service';
#Component({
selector: 'page-register',
templateUrl: './register.page.html',
styleUrls: ['./register.page.scss'],
})
export class RegisterPage{
loading: any;
regData = {name: '', icNumber: '', email: '',
password: '', phone: '', address: '',
cityState: '', houseType: '', category:''};
constructor(public navCtrl: NavController, public authService: AuthServiceService, public loadingCtr: LoadingController, private toastCtrl: ToastController) { }
doSignup(){
this.authService.register(this.regData).then((result)=>{
this.loading.dismiss();
this.navCtrl.pop();
}, (err) => {
this.presentToast(err);
});
}
async presentToast(msg){
const toast = await this.toastCtrl.create({
message: msg,
duration: 3000,
position: 'top',
color: 'dark',
});
toast.present();
}
}
**register.html file**
<ion-content padding>
<h2>Register Here</h2>
<form (submit) = "doSignup()">
<ion-item>
<ion-label stacked>Username</ion-label>
<ion-input [(ngModel)] = "regData.name" name = "name" type="text" placeholder = "Your Name"></ion-input>
</ion-item>
<ion-item>
<ion-label stacked>IC-Number</ion-label>
<ion-input [(ngModel)] = "regData.icNumber" name = "icNumber" type="number" placeholder = "Your IC-Number"></ion-input>
</ion-item>
<ion-item>
<ion-label stacked>E-mail</ion-label>
<ion-input [(ngModel)] = "regData.email" name = "email" type="email" placeholder = "Your E-Mail"></ion-input>
</ion-item>
<ion-item>
<ion-label stacked>Password</ion-label>
<ion-input [(ngModel)] = "regData.password" name = "password" type="password" placeholder = "Your Password"></ion-input>
</ion-item>
<ion-item>
<ion-label stacked>Handphone Number</ion-label>
<ion-input [(ngModel)] = "regData.phone" name = "phone" type="tel" placeholder = "Your Phone Number"></ion-input>
</ion-item>
<ion-item>
<ion-label stacked>Address</ion-label>
<ion-input [(ngModel)] = "regData.address" name = "address" type="text" placeholder = "Your Address"></ion-input>
</ion-item>
<ion-item>
<ion-label stacked>City/State</ion-label>
<ion-input [(ngModel)] = "regData.cityState" name = "cityState" type="text" placeholder = "Your City/State"></ion-input>
</ion-item>
<ion-item>
<ion-label stacked>House Type</ion-label>
<ion-input [(ngModel)] = "regData.houseType" name = "houseType" type="text" placeholder = "Your House Type"></ion-input>
</ion-item>
<ion-item>
<ion-label stacked>Category</ion-label>
<ion-select [(ngModel)] = "regData.category" name = "category" type="text" placeholder = "Your Category">
<ion-select-option value="1" selected>Maid</ion-select-option>
<ion-select-option value="2" selected>Customer</ion-select-option>
</ion-select>
</ion-item>
<button ion-button block type = "submit">
SignUp
</button>
</form>
</ion-content>
This seems like a CORS issue, To avoid CORS problem you must use #ionic-native/HTTP plugin which is actually Advanced HTTP plugin for API calls.
Follow below steps to use this plugin
Step 1: Add Http native plugin
$ ionic cordova plugin add cordova-plugin-advanced-http
$ npm install --save #ionic-native/http
Installation Link : HTTP
Step 2: Import HTTP native plugin in your file where you wants to call API.
import { HTTP, HTTPResponse } from '#ionic-native/http';
Step 3: How to use this plugin for API call ?
constructor(public httpPlugin: HTTP) {
}
//Set header like this
this.httpPlugin.setHeader("content-type", "application/json");
//Call API
this.httpPlugin.get(this.url, {}, {}).then((response) => {
//Got your server response
}).catch(error => {
//Got error
});

Ionic2 JWT authentication failed with Django rest framework backend

I am building an Ionic 2 app and I am trying to use JWT to authenticate my users as shown here: https://auth0.com/blog/2016/02/18/ionic-2-authentication-how-to-secure-your-mobile-app-with-jwt/.
On clicking 'login' server sends back the token which I can see in my developer console network, however I get following error on console: (Error in build/pages/profile/profile.html:8:29 & ORIGINAL EXCEPTION: Error: JWT must have 3 parts.)Additionally I have to clear cookies everytime!
My profile.ts:
import {Page, Storage, LocalStorage} from 'ionic-angular';
import {Http, Headers} from '#angular/http';
import {FORM_DIRECTIVES} from '#angular/common';
import {JwtHelper} from 'angular2-jwt';
import {AuthService} from '../../services/auth/auth.service';
import 'rxjs/add/operator/map';
import { NavController, NavParams } from 'ionic-angular';
import { StartPage } from '../start/start.component';
#Page({
templateUrl: 'build/pages/profile/profile.html',
directives: [FORM_DIRECTIVES]
})
export class ProfilePage {
LOGIN_URL: string = " http://127.0.0.1:8000/rest-auth/login/";
SIGNUP_URL: string = "http://127.0.0.1:8000/rest-auth/registration/";
auth: AuthService;
// When the page loads, we want the Login segment to be selected
authType: string = "login";
// We need to set the content type for the server
contentHeader: Headers = new Headers({"Content-Type": "application/json"});
error: string;
jwtHelper: JwtHelper = new JwtHelper();
local: Storage = new Storage(LocalStorage);
user: string;
constructor(private http: Http, public nav:NavController) {
this.auth = AuthService;
this.local.get('profile').then(profile => {
this.user = JSON.parse(profile);
}).catch(error => {
console.log(error);
});
}
login(credentials) {
this.http.post(this.LOGIN_URL, JSON.stringify(credentials), { headers: this.contentHeader })
.map(res => res.json())
.subscribe(
data => this.authSuccess(data.id_token),
err => this.error = err
);
}
signup(credentials) {
this.http.post(this.SIGNUP_URL, JSON.stringify(credentials), { headers: this.contentHeader })
.map(res => res.json())
.subscribe(
data => this.authSuccess(data.id_token),
err => this.error = err
);
}
logout() {
this.local.remove('id_token');
this.user = null;
}
authSuccess(token) {
this.error = null;
this.local.set('id_token', token);
this.user = this.jwtHelper.decodeToken(token);
}
}
My service:
import {tokenNotExpired} from 'angular2-jwt';
export class AuthService {
constructor() {}
public static authenticated() {
return tokenNotExpired();
}
}
My profile.html:
<!-- app/profile/profile.html -->
<ion-navbar *navbar>
<button menuToggle>
<ion-icon name="menu"></ion-icon>
</button>
<ion-title>Profile</ion-title>
</ion-navbar>
<ion-content class="login" *ngIf="!auth.authenticated()">
<div padding>
<ion-segment [(ngModel)]="authType">
<ion-segment-button value="login">
Login
</ion-segment-button>
<ion-segment-button value="signup">
Signup
</ion-segment-button>
</ion-segment>
</div>
<div [ngSwitch]="authType">
<form *ngSwitchWhen="'login'" #loginCreds="ngForm" (ngSubmit)="login(loginCreds.value)">
<ion-item>
<ion-label>Username</ion-label>
<ion-input type="text" ngControl="email"></ion-input>
</ion-item>
<ion-item>
<ion-label>Password</ion-label>
<ion-input type="password" ngControl="password"></ion-input>
</ion-item>
<div padding>
<button block type="submit">Login</button>
</div>
</form>
<form *ngSwitchWhen="'signup'" #signupCreds="ngForm" (ngSubmit)="signup(signupCreds.value)">
<ion-item>
<ion-label>Username</ion-label>
<ion-input type="text" ngControl="username"></ion-input>
</ion-item>
<ion-item>
<ion-label>Password</ion-label>
<ion-input type="password" ngControl="password"></ion-input>
</ion-item>
<div padding>
<button block type="submit">Signup</button>
</div>
</form>
</div>
<div padding>
<p *ngIf="error" class="error">{{ error._body }}</p>
</div>
</ion-content>
<ion-content>
<div *ngIf="auth.authenticated()">
<div padding>
<h1>Welcome, {{ user }}</h1>
<button block (click)="logout()">Logout</button>
</div>
</div>
</ion-content>
On successful login I would like to navigate to a specific page. What's going wrong and how can I fix this?
Also, the token I get back from my backend (I am using Django-rest-auth in my backend for authentication):