Saving and Getting Data / Rows to and from PouchDB - angularjs

i am very new to pouchdb, meaning i have not yet been successfully able to implement an app that uses it.
This is my issue now, in my controller i have two functions:
var init = function() {
vm.getInvoicesRemote(); // Get Data from server and update pouchDB
vm.getInvoicesLocal(); // Get Data from pouchDB and load in view
}
init();
Basically in my app i have a view that shows customer invoices, now i want customers to be able to still see those invoices when they're offline. I have seen several examples of pouchdb and couchdb but all use the "todo" example which does not really give much information.
Now i'm just confused about what the point was in me spending hours understanding couchdb and installing it if in the end i'm just going to be retrieving the data from my server using my API.
Also when the data is returned how does pouchdb identify which records are new and which records are old when appending.

well, i m working on same kind..!this is how i m making it work..!
$scope.Lists = function () {
if(!$rootScope.connectionFlag){
OfflineService.getLocalOrdersList(function (localList) {
if(localList.length > 0) {
$scope.List = localList;
}
});
}else{
if(!$scope.user){
}else {
Common.callAPI("post", '***/*************', $scope.listParams, function (data) {
if (data !== null) {
$scope.List = data.result;
OfflineService.bulkOrdersAdd_updateLocalDB($scope.List);
}
});
}
}
};
so,$scope.List will be filled if online as well as offline based on connectionFlag
note : OfflineService and Common are services.
call method:
$ionicPlatform.ready(function () {
OfflineService.configDbsCallback(function(res) {
if(res) {
$scope.Lists();
}
});
});
u can try calling $scope.Lists(); directly..!
hope this helps u..!

Related

Hive database not working offline while works fine when connected to internet

I am developing a flutter application in which I am implementing hive database for caching data.
I have added both hive and hive_flutter packages.
I am getting data from APIs and store that to hive to update data, It works fine when I used app connected to internet but didn't works when I try to read while being offline. Here is the code of my API method I am calling to get data:
static Future<List<UserPost>> getPosts() async {
//I call my API in try block, if its successful, I update the data in hive
List<UserPost> posts = [];
Hive.openBox(Constants.APIDATA_BOX);
try {
var response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts'),);
if (response.statusCode == 200) {
//Clear hive box from old data
Hive.box(Constants.APIDATA_BOX).clear();
Hive.box(Constants.APIDATA_BOX).put(Constants.API_DATA,jsonDecode(response.body));
}
} catch (e) {
print('You are not connected to internet');
}
//I am getting data here from hive database and it works fine while connected to internet
var listMaps =await Hive.box(Constants.APIDATA_BOX).get(Constants.API_DATA, defaultValue: []);
posts = listMaps.map<UserPost>((map) {
//Here flow stucked whenever working offline,
//Data is also available but here conversion cause error, I have tried many way but fails.
return UserPost.fromMap(map);
}).toList();
return posts;
}
I don't why I am getting error, I have tried many conversion ways here but all works while being online. Any help will be highly apprerciated.
I think I've understood the error but you should explain better which type of error you're having.
Anyway pay attention to the operations on Hive, which are often async, for example Hive.openBox(Constants.APIDATA_BOX);.
So when you have internet connection, you have to await for the response and Hive has time to open the box, otherwise it will throw an error so, considering the futures, you should do this:
static Future<List<UserPost>> getPosts() async {
List<UserPost> posts = [];
await Hive.openBox(Constants.APIDATA_BOX);
try {
var response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts'),);
if (response.statusCode == 200) {
//Clear hive box from old data
await Hive.box(Constants.APIDATA_BOX).clear();
await Hive.box(Constants.APIDATA_BOX).put(Constants.API_DATA,jsonDecode(response.body));
}
} catch (e) {
print('You are not connected to internet');
}
var listMaps = await Hive.box(Constants.APIDATA_BOX).get(Constants.API_DATA, defaultValue: []);
posts = listMaps.map<UserPost>((map) {
return UserPost.fromMap(map);
}).toList();
return posts;
}
Note that await Hive.put() in a normal box is not strictly necessary, as explained in the docs

kinvey fetching and remove not working (AngularJS)

I have this problem with kinvey backend,
I'm trying to fetch data from my collection but it doesn't work for me. here is my code :
var query = new $kinvey.Query();
query.equalTo('_id', '5909e8084c68b1ef74fa4efc');
var dataStore = $kinvey.DataStore.collection('User1Bases', $kinvey.DataStoreType.Network);
var stream = dataStore.find(query);
stream.subscribe(function onNext(entity) {
// ...
}, function onError(error) {
// ...
}, function onComplete() {
//...
});
Can you help me please
If you let run the code you have posted then consider four things:
Make sure you have Kinvey implemented:
<script src="https://da189i1jfloii.cloudfront.net/js/kinvey-html5-sdk-3.10.2.min.js"></script>
Make sure you have initialized the Kinvey service before:
// Values shown in your Kinvey console
Kinvey.init({
appKey: '<your_appKey>',
appSecret: 'your_appSecret'
});
Make sure you are logged in with a user that has the rights to read your collection (should be fine using the All Users role (default)):
var promise = Kinvey.User.login('<username>', '<password>')
.then(function() {
console.log ("You are logged in");
})
.catch(function(error) {
console.log (error);
});
Output the return result to see whats coming back. To make sure you do the query AFTER successful login, paste you query inside the .then function of login.
I'm not sure if your query is valid unter 3.x since a lot has changed and I'm not working with older Kinvey versions.
So that all together would look like this:
// Initialize Kinvey
Kinvey.init({
appKey: '<your_appKey>',
appSecret: 'your_appSecret'
});
// Login with already registered user
var promise = Kinvey.User.login('<username>', '<password>')
.then(function() {
console.log ("You are logged in");
// Your query
var query = new $kinvey.Query();
query.equalTo('_id', '5909e8084c68b1ef74fa4efc');
var dataStore = $kinvey.DataStore.collection('User1Bases', $kinvey.DataStoreType.Network);
var stream = dataStore.find(query);
stream.subscribe(function onNext(entity) {
// Output of returning result
console.log (entity);
// ...
}, function onError(error) {
// ...
}, function onComplete() {
//...
});
})
.catch(function(error) {
console.log (error);
});
There are now three return sets possible:
Nothing (as you say) -> Something missing/wrong in the code (compare yours with mine)
Empty array: Your query didn't find anything, adapt the search value(s)
One or more entries in the array -> All fine, what you were looking for!
Hope that helps!
When querying by _id there is a built in method: http://devcenter.kinvey.com/angular/guides/datastore#FetchingbyId
Try switching to var stream = dataStore.findById('entity-id');
Also check to make sure you don't have any preFetch or postFetch BL that is interfering with the query.

Create a favorite list in Ionic Framework

I am very new to Ionic Framework. I am learning the framework and have tried to build a simple android app, which displays a simple list using json. Now, I want add a favorite list which will show user selected items in it. When user clicks on a button it should add that item in a favorite list. And When user click on Favorite tab it should show list of all favorite items.
At present I am trying to do this with simple json and global controller. But I am afraid if this is used on android app on a phone it will not store all favorites, it would remove all favourites once app is closed. Can anyone please suggest a better approach towards it.
Many thanks in advance.
I see you tagged the question with local storage, so why not use that? Also, you could use one of the popular mBaaS solutions like Firebase or gunDB.
As for the logic, it's quite easy: you create a new array which you use for storing these favorites (you handle the adding/removing on the favorite button click). You then use the ng-repeat on the Favorites tab to list the favorites array.
The best way to do this would be pouchdb, i m using in same way.!
Install pouchdb using command:
bower install pouchdb
add below line in index.html
<script src="lib/pouchdb/dist/pouchdb.min.js"></script>
make a service:
.factory('FavService', function (UserService) {
var FavService = {};
var localDB;
var user = UserService.getUser();
if (user) {
localDB = new PouchDB('u_' + user.id);
}
FavService.configDbs = function () {
//console.log('config dbs');
var user = UserService.getUser();
if (user) {
localDB = new PouchDB('u_' + user.id);
}
};
FavService.storeToLocal = function (product) { //change function name
if (localDB && product !== "") {
localDB.post(product);
// console.log("Action completed");
} else {
// console.log("Action not completed");
}
};
FavService.getLocalList = function (callback) {
if (localDB) {
localDB.allDocs({
include_docs: true
}).then(function (response) {
// console.log("response :"+JSON.stringify(response));
localDB = response.rows;
callback(response.rows);
}).catch(function () {
callback(null);
});
} else {
FavService.configDbs();
}
};
});

Creating and adding to arrays in angularFire / Firebase

I am trying to build an app with angularjs and Firebase similar to a forum for helping my classmates with problems. I also want people to be able to 'reply' to the specific problems the classmates are having, so I create an object with many values in the angularjs factory, like this:
factory.addError = function() {
factory.errors.$add({
...
replies: []
});
};
The problem with this is that Firebase doesn't save parameters with empty values for placeholders, such as the parameter 'replies' above. I have tried to hard code a placeholder value into the array, but that seems like a very patchy solution, and that comes with it's own set of problems for me having to delete out the data in Firebase. For reference, here is the code in the linked controller:
$scope.error.replies.$push({
name: $scope.replyName,
message: $scope.replyMessage,
time: (new Date()).toString(),
upvote: 0
});
How do you initialize an empty array into the object? And will $push properly use Firebase's commands to save it to it's own set of data?
First, here are some relevant resources and suggestions:
Resources
Check out Firebase's blog post, Best Practices: Arrays in Firebase - "Arrays are evil".
Also, the AngularFire Development Guide.
And the documentation for AngularJS providers.
Suggestions
As the AngularFire API Documentation says:
"There are several powerful techniques for transforming the data downloaded and saved by $firebaseArray and $firebaseObject. These techniques should only be attempted by advanced Angular users who know their way around the code."
Putting all that together, you accomplish what you want to do by:
Extending AngularFire services, $firebaseArray and $firebaseObject.
Following the documentation for extending services.
Example
Extended Error $firebaseObject
.factory('Error', function(fbUrl, ErrorFactory) {
return function(errorKey){
var errorRef;
if(errorKey){
// Get/set Error by key
errorRef = new Firebase(fbUrl + '/errors/'+errorKey);
} else {
// Create a new Error
var errorsListRef = new Firebase(fbUrl + '/errors');
errorRef = errorsListRef.push();
}
return new ErrorFactory(errorRef);
}
})
.factory('ErrorFactory', function($firebaseObject){
return $firebaseObject.$extend({
sendReply: function(replyObject) {
if(replyObject.message.isNotEmpty()) {
this.$ref().child('replies').push(replyObject);
} else {
alert("You need to enter a message.");
}
}
});
})
Error Controller
.controller('ErrorController',function($scope, Error) {
// Set empty reply message
$scope.replyMessage = '';
// Create a new Error $firebaseObject
var error = new Error();
$scope.error = error;
// Send reply to error
$scope.reply = function(){
error.sendReply({message:$scope.replyMessage});
}
})
And String.prototype.isNotEmpty()
String.prototype.isNotEmpty = function() {
return (this.length !== 0 && this.trim());
};
(adapted from this answer)
Hope that helps!

Connection state with doowb/angular-pusher

I am trying to build an Angular project with Pusher using the angular-pusher wrapper. It's working well but I need to detect when the user loses internet briefly so that they can retrieve missed changes to data from my server.
It looks like the way to handle this is to reload the data on Pusher.connection.state('connected'...) but this does not seem to work with angular-pusher - I am receiving "Pusher.connection" is undefined.
Here is my code:
angular.module('respondersapp', ['doowb.angular-pusher']).
config(['PusherServiceProvider',
function(PusherServiceProvider) {
PusherServiceProvider
.setToken('Foooooooo')
.setOptions({});
}
]);
var ResponderController = function($scope, $http, Pusher) {
$scope.responders = [];
Pusher.subscribe('responders', 'status', function (item) {
// an item was updated. find it in our list and update it.
var found = false;
for (var i = 0; i < $scope.responders.length; i++) {
if ($scope.responders[i].id === item.id) {
found = true;
$scope.responders[i] = item;
break;
}
}
if (!found) {
$scope.responders.push(item);
}
});
Pusher.subscribe('responders', 'unavail', function(item) {
$scope.responders.splice($scope.responders.indexOf(item), 1);
});
var retrieveResponders = function () {
// get a list of responders from the api located at '/api/responders'
console.log('getting responders');
$http.get('/app/dashboard/avail-responders')
.success(function (responders) {
$scope.responders = responders;
});
};
$scope.updateItem = function (item) {
console.log('updating item');
$http.post('/api/responders', item);
};
// load the responders
retrieveResponders();
};
Under this setup how would I go about monitoring connection state? I'm basically trying to replicate the Firebase "catch up" functionality for spotty connections, Firebase was not working overall for me, too confusing trying to manage multiple data sets (not looking to replace back-end at all).
Thanks!
It looks like the Pusher dependency only exposes subscribe and unsubscribe. See:
https://github.com/doowb/angular-pusher/blob/gh-pages/angular-pusher.js#L86
However, if you access the PusherService you get access to the Pusher instance (the one provided by the Pusher JS library) using PusherService.then. See:
https://github.com/doowb/angular-pusher/blob/gh-pages/angular-pusher.js#L91
I'm not sure why the PusherService provides a level of abstraction and why it doesn't just return the pusher instance. It's probably so that it can add some of the Angular specific functionality ($rootScope.$broadcast and $rootScope.$digest).
Maybe you can set the PusherService as a dependency and access the pusher instance using the following?
PusherService.then(function (pusher) {
var state = pusher.connection.state;
});
To clarify #leggetters answer, you might do something like:
app.controller("MyController", function(PusherService) {
PusherService.then(function(pusher) {
pusher.connection.bind("state_change", function(states) {
console.log("Pusher's state changed from %o to %o", states.previous, states.current);
});
});
});
Also note that pusher-js (which angular-pusher uses) has activityTimeout and pongTimeout configuration to tweak the connection state detection.
From my limited experiments, connection states can't be relied on. With the default values, you can go offline for many seconds and then back online without them being any the wiser.
Even if you lower the configuration values, someone could probably drop offline for just a millisecond and miss a message if they're unlucky.

Resources