I'm new to AngularJs. How to save data from Api into couchdb using AngularJs and retrieve it back. Can anyone give example coding.
'Cause CouchDB has a REST interface you can use these AngularJS services to access its functionalities:
$resource
$http
Eventually here is a tutorial with a step-by-step example:
http://thewebhacker.com/rapid-app-prototyping-with-angularjs-and-couchdb/
Refer this dummy code, this will basically calls URL defined by Couch and returns JSON data,
function getItems () {
$http.get(appSettings.db + '/_design/expenses/_view/byName')
.success(function (data) {
$scope.items = data.rows;
});
}
getItems();
For more info, plz refer this link:
http://www.sitepoint.com/tracking-expenses-couchdb-angular/
Related
I have a form in angular where a user enters various criteria which I then want to pass to Web Api and get a result after queries are run. I originally thought of this as a "Get" but had trouble passing complex objects to the Web Api. With some advice, I then used a Post and was able to pass the criteria run the query in the Web Api but I had trouble getting the result back in Angular. The Web Api method is run and gets the results. But I don't see the results in the data service.
What is the best approach where the criteria for a query is multiple fields and some are lists? I haven't been able to find any good examples.
Here is the Web Api method:
[HttpPost]
public IEnumerable Post([FromBody] FrequentPawnerReportCriteria criteria)
{
var repo = new FrequentPawnerReport();
var result = repo.GetReport(criteria);
return result;
}`
Here is the dataservice:
function getFrequentPawner(criteria) {
return $http.post("/api/FrequentPawner/Post", criteria)
.then (getFrequentPawnerComplete)
.catch(getFrequentPawnerFailed);
function getFrequentPawnerComplete(response) {
var x = response
return response.data.results;
}
function getFrequentPawnerFailed(error) {
alert("XHR failed for frequent pawner report: " + error.responseText);
}
}
And here is the controller code:
function getTopPawnerResults(criteria) {
return DataContext.getFrequentPawner(criteria)
.then(
function (result) {
vm.frequentPawnerReport = result.data;
return vm.frequentPawnerReport;
});
}
Simply use JSON. Use JSON.stringify() to parse JSON object to string and POST it. Similarly, return JSON string from server, and assign it to variable in Angular. It will be automatically converted to JSON object.
I think when you make your post request, you need to have a callback function that would get invoked when your Web Api returns. Within that callback function you can update your $scope variables which will make your web ui show the response from the server. You can find an example of what I mean here: https://docs.angularjs.org/api/ng/service/$http
The gist of it:
$http({
method: 'POST',
url: '/path/to/your/web/api',
function(success) {
console.log('Successfully executed the api call');
$scope.response = response; // change this to match the data you are expecting from the server response
},
function(failure) {
console.error('There was an error');
$scope.failure = failure; // change this to match your failure response
}
);
Thanks for responding. The project is a mix of web forms and angularjs. I am migrating the app and didn't notice this form had a conflict which was causing a post back and making it look like the result was not being returned. I took the form into a separate project and was able to get the results I was going for.
I want to develop set of functions(sort of library) for CRUD in AngularJS so I can reuse them for couple of entities of my project. For server communication I made factory of $resource and using accordingly. $resource factory looks like this:
Model File:
var get_entity_model = angular.module("app.getentity", []).factory('getEntity', ['$resource', function($resource) {
return{
entity_view: $resource(baseurl+'/rest/'+serviceName+'/entity/:id/?app_name='+appName+'&fields=*', null, {'update': { method:'PUT' }})
}
}]);
And here how I'm using it in controller
Controller File:
getEntity.entity_view.get(
function(entity_list){
},
function(error){
}
)
Here entity_view is the table name. I'm passing all related functions like pagination and sub request to get the data of related tables etc code I put into success function of above request.
Now I want to make a library where I can define all this stuff and simply by calling the function I should be able to get all this stuff like:
entity.getEntity()
Should return same result as above code.
I tried with creating factory for above task but seems it need callback function and function at factory will return only data which I'm already getting from my model file so I need to make it compact and easy to use.
Factory Code at factory file:
var api = angular.module("app.entity_api", []).factory('entity_factory', ['$resource','getEntity',function($resource,getEntity) {
var entity_factory = {};
entity_factory.get_entity = function(callback){
getEntity.entity_view.get().$promise.then(
function(data){
callback(data.record);
}
);
}
return entity_factory;
}]);
And here how I call the function in controller:
Controller code:
api.controller("sample",['entity_factory','getEntity','$scope',function(entity_factory,getEntity,$scope){
$scope.init = function(){
entity_factory.get_entity(
function(data){
console.log(data);
}
);
}
$scope.init();
}])
Problem is that my entity_factory code will return only the data from server rest of the additional code I've to do in callback function which seems not much difference than my current exercise. So, the question is how can I achieve my goal to make a library of functions with additional code which return complete compiled result to make the code reusable for other entities and compact.
I like that you're a thinking of making a library but in this case, don't reinvent the wheel and save your precious time. Check out Restangular and your task will be a lot easier. Restangular is an AngularJS service that simplifies common GET, POST, DELETE, and UPDATE requests with a minimum of client code. It's a perfect fit for any WebApp that consumes data from a RESTful API.
I am trying to make Breeze.JS to make use of angular's http service for ajax calls. I followed the the docs (http://www.breezejs.com/documentation/customizing-ajax) and applied it. However it doesn't work.
Further more when I checked breeze source code I saw the following:
fn.executeQuery = function (mappingContext) {
var deferred = Q.defer();
var url = mappingContext.getUrl();
OData.read({
requestUri: url,
headers: { "DataServiceVersion": "2.0" }
},
function (data, response) {
var inlineCount;
if (data.__count) {
// OData can return data.__count as a string
inlineCount = parseInt(data.__count, 10);
}
return deferred.resolve({ results: data.results, inlineCount: inlineCount });
},
function (error) {
return deferred.reject(createError(error, url));
}
);
return deferred.promise;
};
It simply calls OData.read without doing anything about http service. Thus OData makes use of builtin ajax. I don't understand with above code, how it is possible to customize ajax of Breeeze.JS
The problem is that the Breeze OData path does NOT use the Breeze Ajax adapter. Changing the Breeze Ajax Adapter (as the "Breeze Angular Service" does) won't help.
At the moment, both the "OData" and "webApiOData" DataService Adapters delegate to the 3rd party datajs library for AJAX services (and for other OData-related support).
You could replace its odata.defaultHttpClient with a version of your own based on $http. That's not a trivial task. Look here for the source code; it's roughly 160 lines.
I suppose we could write one. It hasn't been a priority.
Until somebody does it or we abandon datajs (not soon if ever), you're stuck with the datajs ajax.
Sorry about that.
p.s. Just about everyone who talks to OData data sources uses the datajs library. Maybe you can talk to the authors of that library and try to get them to support$http.
Quick and dirty hack to simulate $http service
I ran into this issue today. Since the external datajs AJAX methods are used rather than Angular's $http service (as explained by Ward), Breeze queries do not trigger a digest and the models do not get updated.
As with any external-to-angular changes, the simple solution is to wrap any assignments from your queries in a $scope.$apply() function. However, this will quickly clutter up your app so it's a bad idea.
I came up with a quick and dirty hack that so far seems to work well:
I have a dataContextservice which encapsulates all my Breeze queries and exposes methods like getCustomers(), getProducts() etc (inspired by the example on the Breeze site).
When any of these data-access methods completes (ie the promise resolves), I call a triggerAngularDigest() method.
This method simple calls $rootScope.$apply() inside a $timeout().
The $timeout() causes Angular to run the digest on the next tick, i.e. after the data from your Breeze query has been assigned to your models.
All your models update just like when you use $http, no need to call $apply() in your controllers.
Simplified version:
function dataContext($rootScope, $timeout, breeze) {
// config of entity manager etc snipped
return {
getCustomers: function () {
return breeze.EntityQuery.from('Customers')
.using(manager)
.execute()
.then(function(data) {
triggerAngularDigest(); // <-- this is the key
return data;
});
}
};
function triggerAngularDigest() {
$timeout(function() {
$rootScope.$apply();
}, 0);
}
}
myApp.factory('dataContext', dataContext);
Then:
// some controller in your app
dataContext.getCustomers().then(function(data) {
scope.customers = data;
});
I'm making a mobile app using ionic (based on the AngularJS framework) where I want to display data from a RESTfull API. I'm pretty new to AngularJS so I'm not familiar with the best practices. I want to get data from this API but with a weeknumber parameters in the URL so I can get data from specific weeks. I have looked especially to the example of the AngularJS website.
This is what I have in my services:
var eventServices = angular.module('starter.services', ['ngResource']);
eventServices.factory('EventServiceAPI',['$resource',
function($resource) {
return $resource('http://localhost:8080/schedulingAPI/plannedevents?weeknumber=:weeknumber', {}, {
query: { method: 'GET', params:{weeknumber:'weeknumber'}, isArray: true}
});
}]);
This is what I have in my controller to get the API data:
$scope.events = EventServiceAPI.get({weeknumber: 7});
However, I still keep getting the error:
Error: [$resource:badcfg] object
When I use the full API URL in services and $scope.events = EventServiceAPI.query() in my controller, the full API-data is displayed without error.
I also don't get where to put the parameters; in the brackets after the resource URL or the params option in the query method.
Edit:
The output of http://localhost:8080/schedulingAPI/plannedevents?weeknumber=:weeknumber
[{"id":2985,"event":{"eventId":589,"subject":"Masterproef","year":2014,"weekNumber":7,"dayNumber":6,"startHour":8,"startMinute":10,"endHour":12,"endMinute":45,"startTime":"2014-02-14T07:10:00Z","endTime":"2014-02-14T11:45:00Z","classgroups":[{"id":8,"name":"4ELICTI"},{"id":4,"name":"4ENAU"},{"id":10,"name":"4ELICTE"},{"id":1,"name":"4CHB"},{"id":3,"name":"4ENEL"},{"id":9,"name":"4EMEM"},{"id":2,"name":"4CHC"},[]],"teacher":null},"rooms":[{"id":24,"abbr":"D015"}]},{"id":4021,"event":{"eventId":604,"subject":"Bedrijfsbeleid 2 hc","year":2014,"weekNumber":7,"dayNumber":6,"startHour":8,"startMinute":10,"endHour":9,"endMinute":35,"startTime":"2014-02-14T07:10:00Z","endTime":"2014-02-14T08:35:00Z","classgroups":[{"id":6,"name":"4ELICT"},[]],"teacher":null},"rooms":[{"id":44,"abbr":"G120"}]}]
Replace params:{weeknumber:'weeknumber'} with params:{weeknumber:'#weeknumber'}, notice the #.
If the parameter value is prefixed with # then the value of that
parameter is extracted from the data object (useful for non-GET
operations).
From angular documentation
And call your function with query:
$scope.events = EventServiceAPI.query({weeknumber: 7});
Actually, you can simplify your resource declaration like this:
eventServices.factory('EventServiceAPI',['$resource',
function($resource) {
return $resource('http://localhost:8080/schedulingAPI/plannedevents');
});
}]);
Angular will automatically append the query string for you
I am using AngularJS Services in my application to retrieve data from the backend, and I would like to make a loading mask, so the loading mask will start just before sending the request. but how can I know when the request ends?
For example I defined my servive as:
angular.module('myServices', ['ngResource'])
.factory('Clients', function ($resource) {
return $resource('getclients');
})
.factory('ClientsDetails', function ($resource) {
return $resource('getclient/:cltId');
})
So I use them in my controller as:
$scope.list = Clients.query();
and
$scope.datails = ClientsDetails.get({
date:$scope.selectedId
});
So the question would be, how to know when the query and get requests ends?
Edit:
As a side note in this question I've been using using angularjs 1.0.7
In AngularJS 1.2 automatic unwrapping of promises is no longer supported unless you turn on a special feature for it (and no telling for how long that will be available).
So that means if you write a line like this:
$scope.someVariable = $http.get("some url");
When you try to use someVariable in your view code (for example, "{{ someVariable }}") it won't work anymore. Instead attach functions to the promise you get back from the get() function like dawuut showed and perform your scope assignment within the success function:
$http.get("some url").then(function successFunction(result) {
$scope.someVariable = result;
console.log(result);
});
I know you probably have your $http.get() wrapped inside of a service or factory of some sort, but you've probably been passing the promise you got from using $http out of the functions on that wrapper so this applies just the same there.
My old blog post on AngularJS promises is fairly popular, it's just not yet updated with the info that you can't do direct assignment of promises to $scope anymore and expect it to work well for you: http://johnmunsch.com/2013/07/17/angularjs-services-and-promises/
You can use promises to manage it, something like :
Clients.query().then(function (res) {
// Content loaded
console.log(res);
}, function (err) {
// Error
console.log(err);
});
Another way (much robust and 'best practice') is to make Angular intercepting your requests automatically by using interceptor (see doc here : http://docs.angularjs.org/api/ng.$http).
This can help too : Showing Spinner GIF during $http request in angular
As left in a comment by Pointy I solved my problem giving a second parameter to the get function as following:
$scope.datails = ClientsDetails.get({
date:$scope.selectedId
}, function(){
// do my stuff here
});