get allDocs from service and controller using pouchdb - angularjs

i have problem how to get data from service and controller. now i want implement CRUD into my web apps.
this is my service.
application.service('Arrears', [
function()
{
var db = new PouchDB('localhost:5984/arrears');
return {
allDocs: function (startKey, endKey, desc) {
db.allDocs({startkey: startKey, endkey: endKey, descending: desc})
.then(function (result) {
console.log(result, 'Results from allDocs');
return result;
})
},
}
}
]);
this is my controller.
application.controller('ArrearsManagementAllController', ['$location', '$mdSidenav', '$scope', 'Arrears',
function($location, $mdSidenav, $scope, Arrears)
{
$scope.items= Arrears.allDocs();
}
]);
and my html like this.
<md-list-item md-virtual-repeat="i in items | orderBy:'status'" ng-click="read(id)">
<b md-highlight-flags="gi">
Status :</b> {{i.status}}
<b md-highlight-text="query.$" style="color:blue"
md-highlight-flags="gi">
{{i.owner_name}}
({{i.owner_id}})
</b>
<p class="md-caption"
md-highlight-text="query.$">
{{i.address}}
</p>
<p class="md-caption"
md-highlight-text="query.$">
{{i.house_no}} - Floor {{i.floor}} -, Lot {{i.lot}} -, Block {{i.block}} - {{i.locality}}
</p>
i'm new with angularjs and pouchdb. please help me.

The issue is that allDocs() doens't return a list of documents; it returns a promise for a list of documents. Check out this post on promises for an overview, but basically you will need to do:
application.service('Arrears', [
function()
{
var db = new PouchDB('localhost:5984/arrears');
return {
allDocs: function (startKey, endKey, desc) {
return db.allDocs({startkey: startKey, endkey: endKey, descending: desc, include_docs: true})
},
}
}
]);
application.controller('ArrearsManagementAllController', ['$location', '$mdSidenav', '$scope', 'Arrears',
function($location, $mdSidenav, $scope, Arrears)
{
$scope.items = [];
Arrears.allDocs().then(function (res) {
$scope.items = res.rows.map(function (row) {
return row.doc;
});
}).catch(console.log.bind(console));
}
Hope that helps!

Related

Angular ng-repeat custom filter giving unresolved variable

Im trying to complete this custom filter to filter a list of all "savings" created in the last 24 hours
Controller filter
angular.module('savings').filter('lessThan', function () {
return function(savings, requirement) {
var filterKey = Object.keys(requirement)[0];
var filterVal = requirement[filterKey];
var filtered = [];
if(filterVal !== undefined && filterVal !== ''){
angular.forEach(savings, function(saving) {
var today = new Date();
var date = new Date(saving.created.$date); <-- Unresolved variable $date
alert(date);
var diff = today - date;
diff = diff / (1000*60*60);
if(diff < filterVal) {
filtered.push(saving);
}
});
return filtered;
}
return savings;
};
});
And here is how i call it from the view
<div ng-repeat="saving in savings | orderBy: '-votesreal' | limitTo:6 | lessThan: {'created.$date':24}" class="col-lg-2 no-padding-spotlight text-center">
<div class=" thumbnail-spotlight thumbnail centred-image">
<img src="{{saving.image}}" /><br>
<a class="text-center" ng-href="/savings/{{saving._id}}" ng-bind="saving.title +' (€'+ saving.price +' # '+ saving.retailer+')'"></a>
</div>
</div>
Ive wrote a note where the unresolved variable is. How do i declare the "saving" object which is coming from the database. Without the filter it returns all results fine.
Controller Code
angular.module('savings').controller('SavingsController', ['$scope', '$timeout', '$stateParams', '$location', '$window', 'Authentication', 'Savings', 'FileUploader',
function($scope, $timeout, $stateParams, $location, $window, Authentication, Savings, FileUploader) {
$scope.authentication = Authentication;
$scope.user = Authentication.user;
$scope.savingImageURL = '/modules/users/client/img/profile/saveme-placeholder.png';
// $scope.user.imageURL = '/modules/users/client/img/profile/saveme-placeholder.png';
$scope.imageURL1 = '';
$scope.hottestsorted = true;
$scope.newestsorted = true;
$scope.brandLogo = '/modules/users/client/img/profile/argos-logo.png';
$scope.spotlightSort = Savings.votesreal;
$scope.savings = Savings;
//$scope.user.imageURL = '';
$scope.submitFormSaving = function(isValid) {
$scope.submitted = true;
};
}
]);
Client.service
//Savings service used for communicating with the savings REST endpoints
angular.module('savings').factory('Savings', ['$resource',
function ($resource) {
return $resource('api/savings/:savingId', {
savingId: '#_id'
}, {
update: {
method: 'PUT'
}
});
}
]);
Well it's good to see that $scope.savings has snuck in there. Try something like this:
Instead of $scope.savings = Savings; use:
Savings.query({}, function(resp){
console.log(resp);
$scope.savings = resp;
});
If your api endpoint needs the savingId use:
Savings.query({ savingId: [something] }, function(resp){
console.log(resp);
$scope.savings = resp;
});
This should work for you.

How to check image exist on server or not in angular js?

I have a recent article section where i need to validate whether image is exist or not on server.
I try some tutorial it validate properly but it does not return any value to my ng-if directive.
Here is my recent article section:-
<div ng-controller="RecentCtrl">
<div class="col-md-3" ng-repeat="items in data.data" data-ng-class="{'last': ($index+1)%4 == 0}" bh-bookmark="items" bh-redirect>
<div class="forHoverInner">
<span class="inner">
<span class="defaultThumbnail">
<span ng-if="test(app.getEncodedUrl(items.bookmark_preview_image))" style="background-image: url('{{app.getEncodedUrl(items.bookmark_preview_image)}}'); width: 272px; height: 272px; " class="thumb" variant="2"></span></span></span> </div>
</div></div>
Here is my recent article controller:-
app.controller('RecentCtrl', function($scope, $http, $rootScope, RecentArticleFactory,$q) {
$scope.test = function(url) {
RecentArticleFactory.isImage(url).then(function(result) {
return result;
});
};
})
Here is recent aricle factory code:-
app.factory("RecentArticleFactory", ["$http", "$q", function ($http, $q) {
return {
isImage: function(src) {
var deferred = $q.defer();
var image = new Image();
image.onerror = function() {
deferred.resolve(false);
};
image.onload = function() {
deferred.resolve(true);
};
image.src = src;
return deferred.promise;
},
}
})
But
ng-if="test(app.getEncodedUrl(items.bookmark_preview_image))" does not return any value
Any Idea?
Thats because it is async due to deferred. Try calling the test function and binding the result value to a field in scope.
First, trigger the test function via $watch:
$scope.$watch("data.data", function() {
for(var i = 0; i < $scope.data.data.length; i++) {
var items = $scope.data.data[i];
$scope.test(items);
}
})
Then change your test function as follows:
$scope.test = function(items) {
items.isImageAvailable= false;
RecentArticleFactory.isImage(items.bookmark_preview_image).then(function(result) {
items.isImageAvailable= result;
});
};
})
Finally, you can use this in your view as:
<span ng-if="items.isImageAvailable" ...></span>
Of course you also need to call app.getEncodedUrl in between. But as I could not see, where app is defined, I omitted this. But the conversion is nevertheless necessary.

Creating custom service in Angular using MeanJS

Still very new to MeanJS and Angular, but am trying to get a repeater to use a custom node service that i created
Here is the Angular Template
<section data-ng-controller="AppController">
<section data-ng-controller="GroupsController" data-ng-init="findMyItems()">
<div class="page-header">
<h1>My Groups</h1>
</div>
<div class="list-group">
<a data-ng-repeat="group in groups" data-ng-href="#!/groups/{{group._id}}" class="list-group-item">
<small class="pull-right" data-ng-bind="group.shortId"></small>
<h4 class="list-group-item-heading" data-ng-bind="group.name"></h4>
<small class="list-group-item-text">
Posted on
<span data-ng-bind="group.created | date:'medium'"></span>
by
<span data-ng-bind="group.user.displayName"></span>
</small>
</a>
</div>
<div class="alert alert-warning text-center" data-ng-hide="!groups.$resolved || groups.length">
No Groups yet, why don't you create one?
</div>
</section>
</section>
Here is an array of JSON objects returned from localhost:3000/users/me/groups
[
{
_id: "5407dd31594e810000af4fa0",
user: "5407c78f9ef3025bbf0440f7",
description: "Activating....",
__v: 0,
projects: [ ],
created: "2014-09-04T03:32:01.825Z",
shortId: "bkXtE746M",
name: "Wonder Twins"
},
{
_id: "5407dc49a34a610000af6896",
user: "5407c78f9ef3025bbf0440f7",
description: "Loved watching this one",
__v: 0,
projects: [ ],
created: "2014-09-04T03:28:09.480Z",
shortId: "WJejxZorTz",
name: "Fantastic Four"
},
{
_id: "5407d71839c7de000008cf6b",
user: "5407c78f9ef3025bbf0440f7",
description: "Great group",
__v: 0,
projects: [ ],
created: "2014-09-04T03:06:00.098Z",
shortId: "ZJfKDyN6f",
name: "Leaders of the New School"
}
]
Controller
'use strict';
// Groups controller
angular.module('groups').controller('GroupsController', ['$scope', '$stateParams', '$location', 'Authentication', 'Groups', 'GroupsAPI',
function($scope, $stateParams, $location, Authentication, Groups, GroupsAPI ) {
$scope.authentication = Authentication;
$scope.findMyItems = function() {
GroupsAPI.getGroupsByCurrentUser()
.success(function (groups) {
$scope.groups = groups;
})
.error(function (error) {
$scope.status = 'Unable to load group data: ' + error.message;
});
};
}
]);
I'm not exactly sure what the service is doing in MeanJS
'use strict';
//Groups service used to communicate Groups REST endpoints
angular.module('groups').factory('Groups', ['$resource',
function($resource) {
return $resource('groups/:groupId', { groupId: '#_id'
}, {
update: {
method: 'PUT'
}
});
}
]);
What I'd like to do is something like to do is something like bellow, but not sure if there is a better way
'use strict';
//Groups service used to communicate Groups REST endpoints
angular.module('groups').factory('Groups', ['$resource',
function($resource) {
return $resource('groups/:groupId', { groupId: '#_id'
}, {
update: {
method: 'PUT'
}
});
}
]);
angular.module('groups')
.factory('GroupsAPI', ['$http', function($http) {
var GroupsAPI = {};
GroupsAPI.getGroupsByCurrentUser = function () {
return $http.get('users/me/groups');
};
return GroupsAPI;
}]);
Is there a better way of doing this the MeanJS way?
It's been a long time since you posted this, so you likely figured out a solution already, but for the sake of future readers I'll toss an answer in here.
If I'm understanding what you're trying to do, it looks like you are trying to create a custom factory that functions similar to the existing Groups factory (the one you mentioned you didn't know what it was doing). That's what I'll be answering...
To begin with, you'll want to read the Angular documentation on $resource: https://docs.angularjs.org/api/ngResource/service/$resource. This is what makes the Groups factory work.
To summarize, Angular's $resource allows you to make AJAX requests very easily, by allowing you to create a variable in your controller which has access to REST functions. So basically, you would do something like this:
// Groups controller
angular.module('groups').controller('GroupsController', ['$scope', '$stateParams', '$location', 'Authentication', 'Groups', 'GroupsAPI',
function($scope, $stateParams, $location, Authentication, Groups, GroupsAPI ) {
$scope.authentication = Authentication;
// Since you've added 'Groups' as a dependency, you can now use this "resource" in a new variable.
var groups = new Groups({
// Set any object data you need here, or leave empty.
});
// Now that you have a new instance of your 'Groups' resource (i.e. 'groups'), you can use standard REST calls.
groups.get({
user: currentUser
}, function(results) {
// Do something with results here, e.g.
if(results) {
$scope.groups = results;
} else {
$scope.status = 'Unable to load group data.';
}
});
]);
Note: I haven't tested this code, but this is the idea.

Angular Two way databinding and http.post issue

Objective: Two Way Databinding between database and view via scope and controller
I’m trying to post to a restful database using angular
When I click on the thumbs up or thumbs down the scope changes o.k and is reflected in the view
However how can this placed in real time to a restful database using http post ?
Here’s the HTML
<div ng-controller="ordersCtrl">
<div class="span0 well votingWidget">
<div class="votingButton" ng-click="upVoteOrder(order)">
<i class="icon-thumbs-up "></i>
</div>
<div class="badge ">
<div>{{order.upVoteCount}}</div>
</div>
<div class="votingButton" ng-click="downVoteOrder(order)">
<i class="icon-thumbs-down"></i>
</div>
Heres the Controller: My issue lies here in the http.post command
.controller("ordersCtrl", function ($scope, $http, ordersUrl) {
$scope.downVoteOrder = function(order) {
$scope.selectedOrder = order;
order.upVoteCount--;
$http.post(orderUrl, order.upVoteCount)
.success(function (data) {
$scope.data.orderupVoteCount = data.id;
})
};
});
Note : I can post form data to the restful database successfully using the following code
$scope.sendOrder = function (shippingDetails) {
var order = angular.copy(shippingDetails);
order.products = cart.getProducts();
$http.post(orderUrl, order)
.success(function (data) {
$scope.data.orderId = data.id;
cart.getProducts().length = 0;
})
.error(function (error) {
$scope.data.orderError = error;
}).finally(function () {
$location.path("/uploaded");
});
}
you should use a separate service to handle the http post .
var app = angular.module("myApp", []);
app.factory("OrderService", ["$http", function ($http) {
this.PostDownVote = function(orderUrl, upVoteCount) {
return $http.post(orderUrl, upVoteCount);
}
this.PostOrder = function(orderUrl, order) {
// do something
}
return this;
}]);
Now inject this OrderService to you controller and use it.
app.controller("ordersCtrl", function ($scope, $http, ordersUrl, OrderService) {
$scope.downVoteOrder = function(order) {
$scope.selectedOrder = order;
order.upVoteCount--;
OrderService.PostDownVote(ordersUrl, order.upVoteCount)
.success(data) {// do something}
.error(data) {// do something}
}
});

AngularJS - RestAngular - after post add new category, update category list in other controller

what is the best way to update a list of categories (in a nav for example) after adding a category with a different controller?
Here is my code
// add new category
app.controller('AddCategoryController', ['$scope', 'CategoryService', function($scope, CategoryService) {
$scope.category = {};
$scope.added = false;
$scope.addCategory = function() {
CategoryService.addCategory($scope.category).then(function(response) {
if(response == 'ok') {
$scope.added = true;
}
});
};
}]);
and here is the controller for showing the categories
app.controller('CategoriesController', ['$scope', 'CategoryService', function($scope, CategoryService) {
CategoryService.getCategories().then(function(categories) {
$scope.categories = categories;
});
}]);
Categories are shown in a nav
<nav>
<div class="list-group" ng-controller="CategoriesController">
<a ng-href="#category/{{category.id}}" class="list-group-item" ng-repeat="category in categories" ng-bind="category.name"></a>
</div>
<div class="list-group">
Add category
</div>
</nav>
EDIT This is the service
services.factory('CategoryService', ['$route', 'Restangular', function($route, Restangular) {
var Category = Restangular.all('categories');
return {
getCategories: function() {
return Category.getList();
},
getCategory: function(id) {
id = id ? id : $route.current.params.categoryId;
return Category.get(id);
},
addCategory: function(category) {
return Category.post(category);
},
editCategory: function(category) {
return category.put()
},
removeCategory: function(id) {
id = id ? id : $route.current.params.categoryId;
return Category.remove(id);
}
};
}]);
Services are singleton in AngularJS. Therefore, after you called CategoryService.addCategory you can update the category list in your service and it will be available for other controllers.
You can also enrich your service to cache the categories. This will help you to avoid unnecessary requests to your backend.
Either you build your own caching logic or use:
RestangularProvider.setDefaultHttpFields({cache: true});
In addition you can use $rootScope.$on and $rootScope.$emit to receive and send events. This helps you to communicate between components in real-time fashion.
// send event
$rootScope.$emit(nameOfEvent, args...);
In some other controller/ service
// subscription
var unbind = $rootScope.$on(nameOfEvent, function(event, args...) { /* do stuff */ });
// don't forget to unbind
$scope.$on('$destroy', function() {
unbind();
});

Resources