Lokijs DB data removed after rerun using ionic run command? - android

I am working on a ionic project and trying to use LokiJS. Below is my code,
controller,
$scope.test ={birthdays:[]};
$ionicPlatform.ready(function() {
BirthdayService.initDB();
BirthdayService.getAllBirthdays().then(function(birthdays){
console.log("birthdays=",birthdays);// gives empty array second run...
//var bday1 = {Name:"abrj",Date:new Date()};
//var bday2 = {Name:"abrj2",Date:new Date()};
//BirthdayService.addBirthday(bday1);
//BirthdayService.addBirthday(bday2); added birthdays during the first run.
});
});
I am using cordova-fs-adapter and cordova-file-plugin.
below is my service for adapter integration,
(function() {
angular.module('starter').factory('BirthdayService', ['$q', 'Loki', BirthdayService]);
function BirthdayService($q, Loki) {
var _db;
var _birthdays;
function initDB() {
var fsAdapter = new LokiCordovaFSAdapter({"prefix": "loki"});
_db = new Loki('birthdaysDB',
{
autosave: true,
autosaveInterval: 1000, // 1 second
adapter: fsAdapter
});
};
function getAllBirthdays() {
return $q(function (resolve, reject) {
var options = {
birthdays: {
proto: Object,
inflate: function (src, dst) {
var prop;
for (prop in src) {
if (prop === 'Date') {
dst.Date = new Date(src.Date);
} else {
dst[prop] = src[prop];
}
}
}
}
};
_db.loadDatabase(options, function () {
_birthdays = _db.getCollection('birthdays');
if (!_birthdays) {
_birthdays = _db.addCollection('birthdays');
}
resolve(_birthdays.data);
});
});
};
function addBirthday(birthday) {
console.log("Birthdays=",_birthdays);
_birthdays.insert(birthday);
};
function updateBirthday(birthday) {
_birthdays.update(birthday);
};
function deleteBirthday(birthday) {
_birthdays.remove(birthday);
};
return {
initDB: initDB,
getAllBirthdays: getAllBirthdays,
addBirthday: addBirthday,
updateBirthday: updateBirthday,
deleteBirthday: deleteBirthday
};
}
})();
In first run I am inserting two documents into the birthdays collections.On second run when I trying to check whether they have persisted, they weren't. I know I am doing something wrong.Do suggest.Local storage also gets cleared everytime i rerun(ionic run android)?!

Related

Flutter BloC repeat an event again after dio request time out

I have a problem on my flutter app, when try to load a data from api using dio and this api is private so need to be connected to the same network, so to check everything is fine I tried to connect using mobile data that means dio connection won't success and return timeout, when I call that inside BLoC and use BloCBuilder to build UI depending on state bloc return loadingstate then return errorstate and try to do the event again and fail then repeat this over and over, I just want to avoid this and return error state only and stop listening on that event
void _loadAllSpecialities(
LoadAllSpecialities event, Emitter<DoctorsState> emit) async {
emit(
const DoctorsLoadingState(),
);
emit(const DoctorsLoadingState());
final result = await doctorService.getAllSpeciality(event.jwtToken);
print(result.toString());
//has no error and data loaded
if (result.item1 == null) {
final speicailities = result.item2;
emit(DoctorsSpecialitiesLoaded(specialities: speicailities));
} else {
//has error (error not null)
emit(DoctorErrorState(result.item1!));
}
}```
.
class DoctorService {
final List<DoctorSpeciality> specialities = [];
final options = Options(
responseType: ResponseType.json,
receiveTimeout: 2000,
sendTimeout: 2000,
);
final _dio = Dio();
Future<Tuple<String?, List<DoctorSpeciality>>> getAllSpeciality(
String jwtToken) async {
specialities.clear();
var tuple = Tuple<String?, List<DoctorSpeciality>>(null, []);
try {
final response = await _dio.get<List>(ApiVars.specialitiesEndPoint,
options:
options.copyWith(headers: {"Authorization": "Bearer $jwtToken"}));
if (response.statusCode == 200) {
//has no data
if (response.data == null) {
//set error 1
tuple.setNewValues('No data loaded', []);
//print it
log(tuple.item1 ?? '');
//return tuple with error and empty list
return tuple;
}
//has data then map it into list of specialities
response.data?.forEach((element) {
//convert json to speciality and add it to specialities list
specialities.add(DoctorSpeciality.fromJson(element));
});
//set error to null and list to specialites list
tuple.setNewValues(null, specialities);
return tuple;
} else {
//set error to error with the code and list to empty list
tuple.setNewValues('error occur with code ${response.statusCode}', []);
log(tuple.item1 ?? '');
return tuple;
}
} on DioError catch (error) {
//set error to error message and list to empty list
tuple.setNewValues("doc service ${error.message}", []);
log(tuple.item1 ?? '');
return tuple;
}
}
}
I tried add droppable, sequential and didn't work
on<LoadAllSpecialities>(_loadAllSpecialities, transformer: droppable());
I solved the problem by adding Future before function that called inside the handler function and await it to end as code in below
///constructor called super and pass initial state...
on<DoctorsEvent>(
(event, emit) async {
try {
if (event is LoadAllSpecialities) {
// * load all specialities of doctors from api ...
//add await here
await _loadAllSpecialities(event, emit);
}
} catch (error) {
emit(DoctorErrorState(error.toString()));
}
},
);
}
//add future here
Future<void> _loadAllSpecialities(
LoadAllSpecialities event, Emitter<DoctorsState> emit) async {
emit(
const DoctorsLoadingState(),
);
emit(const DoctorsLoadingState());
final result = await doctorService.getAllSpeciality(event.jwtToken);
//has no error and data loaded
if (result.item1 == null) {
final speicailities = result.item2;
emit(DoctorsSpecialitiesLoaded(specialities: speicailities));
} else {
//has error (error not null)
emit(DoctorErrorState(result.item1!));
}
}

React Native AsyncStorage stops working once app is offline

I have a relatively simple app (my first) that needs to display information that is retrieved from a GraphQL query and then stored in AsyncStorage. Everything works fine until you turnoff data/Wifi connections and relaunch the app - it will not load the same local data it did when networking is on. This is the same on a physical or emulated Android device.
There are no data calls except when the user initially sets their details. The app is built with version 2.7.1 of Expo & AWS Amplify. I have wasted several days with this final issue and gotten the same behaviour with Expo SecureStore & Amplify Cache and am loath to go down the route of learning and including Redux on such a simple app...
//import from react native not react
import { AsyncStorage } from 'react-native'
//calling a function as app loads
componentDidMount() {
this._loadInitialState();
}
//retrieving String from AsyncStorage
_loadInitialState = async () => {
try {
const policyNum = await AsyncStorage.getItem('policyNum')
//...
} catch {
//...
}
//setting state
if (policyNum != null && policyNum != undefined) {
this.setState({ policyNum: policyNum })
//...
}
//the original setting of the item
setPolicyDetails = async () => {
if (this.state.policyNum != null) {
const policyNumber = this.state.policyNum
this.state.policyNumSet = true
try {
await AsyncStorage.setItem('policyNum', policyNumber)
} catch (err) {
//...
}
}
}
You are using badly the fact of change the state.
Where you do this:
this.state.policyNumSet = true
You should change the state with the setState() function like this:
this.setState({ policyNumSet: true })
This was a conflict with an external API
Are you storing a string? asyncstorage only can store strings . try using JSON.stringify and JSON.parse
_loadInitialState = async () => {
try {
var policyNum = await AsyncStorage.getItem('policyNum')
policyNum = JSON.parse(policyNum) // converting to original
//...
} catch {
//...
}
//setting state
if (policyNum != null && policyNum != undefined) {
this.setState({ policyNum: policyNum })
//...
}
//the original setting of the item
setPolicyDetails = async () => {
if (this.state.policyNum != null) {
const policyNumber = this.state.policyNum
this.setState({ policyNumSet: true })
try {
var policyNumberString = JSON.stringify(policyNumber)
await AsyncStorage.setItem('policyNum', policyNumberString) //converting to string
} catch (err) {
//...
}
}
}

Android SQ Lite - How to insert more than 1000 rows at a time efficiently?

I am using Ionic Framework. I want to ask for help about how to insert more than 1000 rows at a time and while insertion showing a loading spinner to user so that there wont be any mess in database.
First, I have two services/factories.
Database :
.factory('DB', function ($ionicPopup, $cordovaSQLite, $q, $ionicPlatform, $cordovaNetwork,$ionicLoading) {
var self = this;
self.query = function (query, parameters) {
parameters = parameters || [];
var q = $q.defer();
$ionicPlatform.ready(function () {
$cordovaSQLite.execute(db, query, parameters)
.then(function (result) {
console.log(result);
q.resolve(result);
}, function (error) {
console.log(error+" .."+error.message);
alert('I found an error' + error.message);
q.reject(error);
});
});
return q.promise;
}
// Proces a result set
self.getAll = function (result) {
var output = [];
for (var i = 0; i < result.rows.length; i++) {
output.push(result.rows.item(i));
}
return output;
}
// Proces a single result
self.getById = function (result) {
var output = null;
output = angular.copy(result.rows.item(0));
return output;
}
return self;
})
Secondly, AsyncService for downloading data from multiple urls
.service('asyncService', function ($http, $q) {
return {
loadDataFromUrls: function (urls) {
alert("I am inside new Service ");
var deferred = $q.defer();
var urlCalls = [];
angular.forEach(urls, function (url) {
urlCalls.push($http.get(url.url));
});
// they may, in fact, all be done, but this
// executes the callbacks in then, once they are
// completely finished.
$q.all(urlCalls)
.then(
function (results) {
deferred.resolve(results)
},
function (errors) {
console.log(errors);
deferred.reject(errors);
},
function (updates) {
console.log(updates);
deferred.update(updates);
});
return deferred.promise;
}
};
})
And the method that firstly, should download the datas and then insert them into their belonged tables.
asyncService.loadDataFromUrls(urLs).then(function (result) {
DB.query("DELETE FROM INV");
// when i have to update the tables, i first delete them and then fill them back again.
$ionicLoading.show({
template : 'Processing into Database. Please Wait...',
timeout : '6000'
});
result.forEach(function (rows) {
console.log(rows.config.url);
var i = 0;
if (rows.config.url == 'http://11.444.222.55:55/mobil_op?op=get_inv') {
rows.data.forEach(function (entry) {
var parameters = [entry.code, entry.name,];
DB.query("INSERT INTO INV (CODE,NAME,......) VALUES(?,?........)",parameters);
})
}
})
}, function (err) {
alert("OOpsss ! : " + err.message);
console.log("error");
}, function (updates) {
alert("updates");
console.log("updates" + updates);
})
How should I work while inserting 4453 elements into array ?
db.executeSql("BEGIN TRANSACTION",{})
.then(( res )=> {
console.log(res);
// DO ALL INSERTION ON THE TABLES
// e.g
// AT LAST
db.executeSql("COMMIT",{})
.then(()=> console.log("COMMIT")
.catch(e => console.log(e));
}).catch(e => console.log(e));
// This process provided me much more faster way . The method above in the question dialog was inserting 4553 items in 3 minutes on Asus Zenphone 1. This method let me insert 10000 items less then 3 minutes.

JSONStore code not working

I am trying to learn JSONStore and in process of that I am trying to execute a piece of code which will first check if a particular JSONStore is already there in the device or not and based on the result it will execute if-else statement. If it is not there, it will create one and add some data in it. In case the jsonStore is already present, code will replace the previously stored data with new data. But when I am trying to execute the code, my device shows the html contents for a while and then the screen gets blank. When I checked the logcat, I didn't get any of my console log statements which I have added in my code. Can anyone please help me in understanding this behavior and what could be done to achieve the requirement.
var JSONStoreCollections = {};
var collectionName = 'Person';
function wlCommonInit(){
require([ "layers/core-web-layer", "layers/mobile-ui-layer" ], dojoInit);
}
function dojoInit() {
require([ "dojo/ready", "dojo/parser", "dojox/mobile", "dojo/dom", "dijit/registry", "dojox/mobile/ScrollableView" ], function(ready) {
ready(function() {
if(!(WL.JSONStore.get(collectionName))){
console.log("i am in if codition");
var Data={
Name:'name',
Age:27
};
JSONStoreCollections[collectionName] = {};
JSONStoreCollections[collectionName].searchFields = {Name: 'string'};
WL.JSONStore.init(JSONStoreCollections)
.then(function () {
console.log("store created");
})
.fail(function (errorObject) {
console.log("store creation failed");
});
WL.JSONStore.get(collectionName).add(Data)
.then(function () {
console.log("data added");
})
.fail(function (errorObject) {
console.log("data addition failed");
});
var query = {Name: 'name'};
WL.JSONStore.get(collectionName)
.find(query)
.then(function (arrayResults) {
console.log(arrayResults);
WL.Logger.debug(arrayResults);
})
.fail(function (errorObject) {
console.log(errorObject);
WL.Logger.debug(errorObject);
});
}
else{
var Data1={
Name:'name1',
Age:30
};
WL.JSONStore.get(collectionName).replace(Data1)
.then(function () {
console.log("data replaced");
})
.fail(function (errorObject) {
console.log("data replacement failed");
});
var query = {Name: 'name1'};
WL.JSONStore.get(collectionName)
.find(query)
.then(function (arrayResults) {
console.log(arrayResults);
WL.Logger.debug(arrayResults);
})
.fail(function (errorObject) {
console.log(errorObject);
WL.Logger.debug(errorObject);
});
}
});
});
}
You need to initialize first, otherwise WL.JSONStore.get(collectionName) will always return undefined. If you never initialize JSONStore, you can not use it.
The replace API works with JSONStore documents (objects that have keys for _id and json).
You only need one .fail, the error object will tell you the source of the error (errorObject.src).
See the untested pseudocode below for what you want to do:
function wlCommonInit () {
var collectionName = 'Person';
var Data = {
Name: 'name',
Age: 27
};
var JSONStoreCollections = {};
JSONStoreCollections[collectionName] = {};
JSONStoreCollections[collectionName].searchFields = {Name: 'string'};
WL.JSONStore.init(JSONStoreCollections)
.then(function () {
WL.Logger.debug('Init done');
return WL.JSONStore.get(collectionName).findAll();
})
.then(function (res) {
WL.Logger.debug('Find All returned:', res);
if (res.length < 1) {
return WL.JSONStore.get(collectionName).add(Data);
} else {
res[0].json = {
Name:'name1',
Age:30
};
return WL.JSONStore.get(collectionName).replace(res[0]);
}
})
.then(function () {
WL.Logger.debug('Add or Replace done');
return WL.JSONStore.get(collectionName).find({Name: 'name'});
})
.then(function (res) {
WL.Logger.info('Final Find returned:', res);
})
.fail(function (err) {
WL.Logger.error(err);
});
}
Expected output the first time executed:
Init done
Find All returned: []
Add or Replace done
Final Find returned: [{"_id":1,"json":{"Name":"name","Age":27}}]
Expected output other than the first time executed:
Init done
Find All returned: [{"_id":1,"json":{"Name":"name","Age":27}}]
Add or Replace done
Final Find returned: [{"_id":1,"json":{"Name":"name1","Age":30}}]

Unity Master Server Vs Simple Client Server

I have written two programs and i want both of these to run on my android device which are on the same network but one which is simple client server program it will run on both device and connection will be made...But Unity Master Server will not run fine and not able to connect two android wifi device which are on the same network and this program will run fine on localhost.
Here is simple client server code..This code run fine
var object:Transform;
static var Isconnected:boolean=false;
//172.16.11.4
function Start()
{
Application.runInBackground = true;
Debug.Log("run in back groud");
}
function Update()
{
if(Isconnected)
var temp:Transform;
temp=Instantiate(object,transform.position, transform.rotation);
}
function OnGUI()
{
if(Network.peerType==NetworkPeerType.Disconnected)
{
if(GUILayout.Button(" Initlized server"))
{
var useNat = !Network.HavePublicAddress();
Network.InitializeServer(32,25001,useNat);
Debug.Log("Server has been Initlized");
}
}
if(GUILayout.Button("connect to server"))
{
Network.Connect("172.16.11.4",25001);
}
}
function OnConnectedToServer() {
Debug.Log("Connected to server");
Isconnected=true;
// Send local player name to server ...
}
But this code will not run on wifi...WHile this code run on localhost if we give the ip 127.0.0.1
#pragma strict
private var rotAngle : float = 0;
private var pivotPoint : Vector2;
var Gamename:String="MyGame";
var refreshing:boolean=false;
private var hostdata:HostData[];
function Start () {
}
function Update () {
var farword=Input.GetKey("up");
if(farword==true)
{
//animation.Play("ArmatureAction");
}
transform.Translate(0,0,Input.GetAxis("Vertical"));
transform.Rotate(0,Input.GetAxis("Horizontal"),0);
if(refreshing)
{
if(MasterServer.PollHostList().Length>0)
{
refreshing=false;
hostdata=MasterServer.PollHostList();
Debug.Log(MasterServer.PollHostList().Length);
}
}
}
function startServer()
{
Network.InitializeServer(32,25001,!Network.HavePublicAddress);
MasterServer.RegisterHost(Gamename,"THis is tutorial","THis is tutorial game");
}
function OnServerInitialized()
{
Debug.Log("Sever is initlized");
}
function OnMasterServerEvent(mgs:MasterServerEvent)
{
if(mgs==MasterServerEvent.RegistrationSucceeded)
{
Debug.Log("Register server");
}
}
function refreshHostList(){
MasterServer.RequestHostList(Gamename);
refreshing=true;
}
function OnGUI()
{
if((!Network.isClient && !Network.isServer))
{
if(GUI.Button(Rect(100,100,100,100),"Start Sever"))
{
Debug.Log("Start Server");
startServer();
}
if(GUI.Button(Rect(100,220,100,100),"Refresg Hosts"))
{
Debug.Log("Refresh HOsts");
refreshHostList();
}
if(hostdata)
{
for(var i:int=0;i<hostdata.length;i++)
{
if(GUI.Button(Rect(230,100,100,100),hostdata[i].gameName))
{
Network.Connect("172.16.11.4",25001);
}
}
}
}
if(GUI.Button(Rect(300,300,100,100),"back"))
{
transform.Translate(9,0,0);
}
if(GUI.Button(Rect(300,400,100,100),"farword"))
{
transform.Translate(-9,0,0);
}
}
Any help
I think in second code
if(hostdata)
{
for(var i:int=0;i<hostdata.length;i++)
{
if(GUI.Button(Rect(230,100,100,100),hostdata[i].gameName))
{
Network.Connect("172.16.11.4",25001);
}
}
need to change
if(hostdata)
{
for(var i:int=0;i<hostdata.length;i++)
{
if(GUI.Button(Rect(230,100,100,100),hostdata[i].gameName))
{
Network.Connect(hostdata[i]); //Or Network.Connect( hostdata[i].ip[ 0 ], hostdata[i].port );
}
}
And also your buttons will overlay themselves. (if more than 1 server initialized and found). You need to create Rect with dynamic start height value. Like:
if(hostdata)
{
var y = 100; // or other start y position like 0
for(var i:int=0;i<hostdata.length;i++)
{
if(GUI.Button(Rect(230,y,100,100),hostdata[i].gameName))
{
Network.Connect(hostdata[i]); //Or Network.Connect( hostdata[i].ip[ 0 ], hostdata[i].port );
}
y+=100+ 5 //Some padding.
}
if any problems occurs like can not connect the server keep in mind NAT punchthrough generally cause problems.

Categories

Resources