Ionic Application not able to update dynamically with database - ionic-framework

I'm connecting ionic application with MySql database using PHP, all functionalities are working fine but when i upload data in database it is taking atleast hour of time for data updation in ionic application, Please find sample code for the same:
I havent used any sessions and when loading component every time will fire request to fetch data from dabase using PHP, tried placing ngZone but still issue remains same.
this.zone.run(() => {
this.http
.get('http://localhost:8100/dbcon/retreive-monthcircular.php')
.subscribe((monthdata : any) =>
{
console.dir(monthdata);
this.loadData = false;
this.circularmonthdata = monthdata;
if (this.circularmonthdata == null) {
this.displayCircular = false;
} else {
this.displayCircular = true;
}
},
(error : any) =>
{
console.dir(error);
});
});
Ideally Application should dynamically update

Look at this example
HTML :
<ion-item>
<ion-label>Date</ion-label>
<ion-datetime displayFormat="DD/MM/YYYY" pickerFormat="DD/MM/YYYY" [(ngModel)]="myDate"></ion-datetime>
</ion-item>
<button ion-button block (click)="getData(myDate)">Get Data</button>
Bellow is your current data from array we created.
<ion-item *ngFor="let data of fetchedData">
Date: {{data.date}} - Description: {{data.description}}
</ion-item>
your TS:
fetchedData = [ // suppose your data looks like this
{
date: '20-02-1990',
description: 'this is First date'
},
{
date: '21-03-1991',
description: 'this is Second date'
}
]
getData(myDate){
this.headers = {'Content-Type': 'application/json'};
this.http.get('http://localhost:8100/dbcon/retreive-monthcircular.php', {headers: this.headers})
.map(res => res.json())
.subscribe(data => {
console.log(data);
this.fetchedData = data.data; // update your variable it will update data on your view.
});
}
by clicking on this function will update your data at DOM. Or you should post your HTML and fetched Data from server.

Related

Handlebars template not rendering data inside of then

Im having a problem with handlebars.
This code works:
const getFacilitators = async () => {
const { data } = await axios.get(`${api_url}/facilitator/list`, {
headers: {
'Authorization': `Bearer ${sessionStorage.getItem('id_token')}`
}
})
return data.Items;
}
getFacilitators()
.then(facilitators => {
if (document.querySelector("#facilitatorTemplate")) {
var facilitatorTemplate = Handlebars.compile(document.querySelector("#facilitatorTemplate").innerHTML);
document.querySelector("#facilitatorSelect").innerHTML = facilitatorTemplate({ facilitators });
//element.value = currentFacilitator.id;
}
});
But it is tripping over a race condition where the currentFacilitator.id is not loaded yet. When I try to put it in a then after the axios call to get that value then it does not seem to render the values from facilitators
.then(() => getFacilitators())
.then(facilitators => {
if (document.querySelector("#facilitatorTemplate")) {
var facilitatorTemplate = Handlebars.compile(document.querySelector("#facilitatorTemplate").innerHTML);
document.querySelector("#facilitatorSelect").innerHTML = facilitatorTemplate({ facilitators });
document.querySelector("#facilitatorSelect").value = currentFacilitator.id;
}
});
Here is the HTML
<template id="facilitatorTemplate">
<select type="text" class="form-control" name="facilitatorId" list="facilitatorsDatalist" autocomplete="off">
{{#each facilitators}}
<option value="{{id}}">{{email}}</option>
{{/each}}
</select>
</template>
<div id="facilitatorSelect">waiting</div>
Full code is visible here
https://github.com/lindsaymacvean/rp/blob/main/docs/scripts/group.js
I went line by line through my HTML and realised that one of the other Handlebar renders was taking the innerHTML which included the template I wanted to render. So in effect the HTML was not available by the time it got to the then in the chain where I wanted to render my second set of data.
My solution was to store the data from the first axios call in a variable that could be accessed later. Then render all the data in one handlebars template in the last then in the chain.

Can I use save my forms into my local database?

I'd like to use form.io in order to allow my admin users to create a new forms but I want save all data into my database, not in form.io platform. Is it possible?
I want use form builder but at save time I want save the form structure into my database.
I don't understand if this option is possible.
Thanks
Yes.
Step 1: Store your components in your database. If you use the form builder, you can get them by a call to builder.schema.
Step 2: Retrieve your components from your database and render the form.
Step 3: Save the data to your DB.
components = {{component string from DB}}
let formio = new Formio.createForm(document.getElementById(element),
components,
{
saveDraft: true,
readOnly: ((readonly) ? readonly : false)
}
).then(function (form) {
if (data) {
var subm = JSON.parse(data)
form.submission = { data: subm };
}
form.on('submit', function (submission) {
//Submission Code
});
form.on('change', function (x) {
//Change Code
})
form.on('error', (errors) => {
//Error Code
})
form.on("render", function () {
//Any Render Overrides?
})
}).catch(function (ex) {
});
Some of this stuff is well documented. Some - not so much. Lots of trial and error. (Mostly error).
Something similar is what works for me. Note this is for saving the schema for the Form Builder. This schema can be deserialized and used as a source for the Form Renderer
#uglyCodeSry
JavaScript
var form;
var formTemplateToSave; // this is the serialized form template to save
window.onload = function() {
var builder = Formio.builder(document.getElementById('builder'), {}, {builder: {}
}).then((_form) => {
form = _form;
form.on('change', function(payload) {
formTemplateToSave = JSON.stringify(form.schema, null, 4);
});
formTemplateToSave = JSON.stringify(form.schema, null, 4);
});
};
HTML
<div>
<div id='builder'></div>
</div>
Don't forget to include the libraries (as well as your usual jquery stuff)
<link rel='stylesheet' href='https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css'>
<link rel='stylesheet' href='https://cdn.form.io/formiojs/formio.full.min.css'>
<script src='https://cdn.form.io/formiojs/formio.full.min.js'></script>
You can then save the formTemplateToSave variable as the JSON to rehydrate your forms

Select multiple images without Image-Picker plugin ionic

I am searching for an alternative to Ionic's image-picker plugin or some guidance on using it to attach a file to a Form for upload. The api that I am using requires that file be uploaded via form. Thoughts or suggestions are much appreciated. The feature of multiple file selection is the most important part of this.
You can use standard web api (file input) to achieve this and use "multiple" as attribute.
Your template:
<button ion-button>
<ion-icon name="image"></ion-icon>
<input multiple type="file” (change)="loadImageFromDevice($event)" accept="image/png, image/jpeg">
</button>
Your ts:
myImages: Array<string>;
...
loadImageFromDevice(event) {
const files = event.target.files;
const blobReader = new FileReader();
files.forEach(file => {
blobReader.readAsArrayBuffer(file);
blobReader.onload = () => {
let blob: Blob = new Blob([new Uint8Array((blobReader.result as ArrayBuffer))]);
let blobURL: string = URL.createObjectURL(blob);
this.myImages.push(blobURL);
};
blobReader.onerror = (error) => {
console.log(error);
};
})
};
I am facing same issue
use this code to choose file in Ionic HTML
<ion-input type="file" (change)="changeListener($event)"></ion-input>
Ts file
changeListener(event) {
var reader = new FileReader();
reader.readAsDataURL(event.target.files[0]);
reader.onload = (_event) => {
this.imgURL = reader.result;
//base64 image
console.log("Image File =>", this.imgURL);
}
}
Then make file controller array and make one button to increase it then you can make multiple file controls to handle and upload to server.
check this for reference
http://masteringionic.com/blog/2018-02-06-dynamically-add-and-remove-form-input-fields-with-ionic/

Ionic list refresh after deleting an item

I am trying to fetch data asynchronously twitter rest API (fetching my tweets to be more specific), and after I do so, I display them as cards. My problem is when I delete a tweet, it does not reflect in my application.
here's a part of my code:
Twitter service provider.
fetchDataFromTwitter() {
return this.httpReader = this.http.get('url').map((resp) => resp).catch((err: any) => {
return Observable.of(undefined);
});
}
twitterList page
public dataFromTwitter:any;
ionViewDidLoad() {
this.tweetProvider.fetchDataFromTwitter().subscribe((data: any) => {
..
..
..
some string manuplation..and iterate threw array of tweets
this.dataFromTwitter.push({
screenName:tweet.user.screen_name,
placeOfId: tweet.full_text.slice(indexStart, indexEnd),
userId: tweet.full_text.slice(indexStartForToken,indexEndForToken)
})
});
}
in the view for the twitterList.html page
<ion-content padding>
<div *ngIf="dataFromTwitter">
<ion-card *ngFor="let data of dataFromTwitter">
<ion-item>
<h2 >user: {{data .placeOfId }}</h2>
</ion-item>
<p>token: {{data.userId}}</p>
<ion-item>
</ion-content>
the example might have errors but, but I hope the idea is clear.
In order to refresh the list after deleting an item, you could choose any one of the following methods
On deleting an element, call the get item call again to refresh the list
Remove(splice) the element from the data source array, this will block the data from showing in the UI.
I will suggest the second one be better.
Maybe you can try this one
Create ion-refresher for your .html files
<ion-refresher slot="fixed" (ionRefresh)="doRefresh($event)">
<ion-refresher-content pullingIcon="arrow-dropdown" pullingText="Pull to refresh" refreshingSpinner="circles"
refreshingText="Refreshing...">
</ion-refresher-content>
Create doRefresh() method on .ts
data: any; // contain array of my data
ngOnInit() {
this.dataSampah();
}
async dataSampah() {
this.session_storage().then(() => {
this.postPrvdr.getData(`tps/invoice?id_tps=` + this.id_tps).subscribe(res => {
this.data = res.data;
}, err => {
console.log(err);
});
});
}
doRefresh(event) {
this.data = null; // this is replacement of splice
this.ngOnInit(); //
setTimeout(() => {
this.router.navigate(['/invoice-sampah']);
event.target.complete();
}, 2000);

Date from input field not being stored

I set up my Angular-Meteor application to allow users editing their date of birth. I am using bootstrap3-datepicker on the input field.
The input field in the form is defined like this:
<div class="form-group">
<label for="dateOfBirth" class="control-label">Date of Birth:</label>
<input type="date" id="dateOfBirth" class="form-control" ng-model="profileEdit.profile.dateOfBirth"/>
</div>
Picking and displaying the date works fine in the front-end, but the date is not stored when I save my form (all other data is). If a date exists before editing the record with the form, the date gets lost.
This is my controller:
class ProfileEdit {
constructor($stateParams, $scope, $reactive) {
'ngInject';
this.profile = Meteor.user().profile;
$('#dateOfBirth').datepicker({
format: "dd.mm.yyyy",
weekStart: 1,
startDate: "01.01.1940",
startView: 2
});
}
save() {
var profile = {
firstName: this.profile.firstName,
lastName: this.profile.lastName,
gender: this.profile.gender,
dateOfBirth: this.profile.dateOfBirth,
level: this.profile.level,
description: this.profile.description
}
Meteor.call('users.profile.update', profile, function(error, result) {
if(error){
console.log("error", error);
}
if(result) {
console.log('Changes saved!');
profile = {}
}
});
}
}
Logging profileEdit.profile.dateOfBirth to the console before saving the form data yields undefined.
It appears to me I am already losing the date between the form and my save() method. Why could this be?
I had the same issue with another datepicker, it appears that when a third party plugin updates the DOM, it does not update the modal that is attached to it. What I had to do was use the datepicker's events to catch the change and programatically update the field, IE:
$('.datepicker').datepicker()
.on('changeDate', function(e) {
// update your model here, e.date should have what you need
});
http://bootstrap-datepicker.readthedocs.io/en/latest/events.html