I am using angular-indexedDB for indexedDB in AngularJS.
I want to receive error if insert is not successful. But I am not getting any error it just comes out of the function if I run the same code twice as I have made name unique.
Error:
ConstraintError return _this.store.add(item);
ConstraintError req =
this.store.openCursor();
Code:
angular.module('myModuleName')
.controller('myControllerName', function($scope, $indexedDB) {
$scope.objects = [];
$indexedDB.openStore('people', function(store){
store.insert({"ssn": "444-444-222-111","name": "John Doe", "age": 57}).then(function(e){console.log('inside insert');});
store.getAll().then(function(people) {
// Update scope
$scope.objects = people;
});
});
});
I think adding error callback inside promise .then should work
Also do create a getAll method to retrieve all data from objects, in that do response.data to get data returned from server.
Code
angular.module('myModuleName')
.controller('myControllerName', function($scope, $indexedDB) {
$scope.objects = [];
$scope.getAll = function(){
store.getAll().then(function(response) {
// Update scope
$scope.objects = response.data;
});
};
$indexedDB.openStore('people', function(store){
store.insert({"ssn": "444-444-222-111","name": "John Doe", "age": 57})
.then(function(e){
console.log('inside insert');
//reload data only call get succeed
$scope.getAll();
}, function(error){
//do error handling stuff here
//you will get error returned from server here.
console.log('Error here', error)
});
});
});
Related
i´m trying to create a factory with angular.js and y have this json structure from the github api:
[
{
"login": "mojombo",
"id": 1,
"avatar_url": "https://avatars.githubusercontent.com/u/1?v=3",
"gravatar_id": "",
"url": "https://api.github.com/users/mojombo",
"html_url": "https://github.com/mojombo",
"followers_url": "https://api.github.com/users/mojombo/followers",
"following_url": "https://api.github.com/users/mojombo/following{/other_user}",
"gists_url": "https://api.github.com/users/mojombo/gists{/gist_id}",
"starred_url": "https://api.github.com/users/mojombo/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/mojombo/subscriptions",
"organizations_url": "https://api.github.com/users/mojombo/orgs",
"repos_url": "https://api.github.com/users/mojombo/repos",
"events_url": "https://api.github.com/users/mojombo/events{/privacy}",
"received_events_url": "https://api.github.com/users/mojombo/received_events",
"type": "User",
"site_admin": false
}]
i want to get the data from the url property that contain the info of the user and the idea is get that data from all the user.
this the my code so far from the factory:
angular
.module('app')
.factory('userFactory', function($http){
function getData(){
return $http.get('https://api.github.com/users');
}
function userData(){
getData().success(function(data){
return $http.get('https://api.github.com/users'+ data.url)
}).error()
}
return{
getData : getData
}
});
and this is the controller:
angular
.module('app')
.controller('listUserController', function($scope, userFactory){
$scope.users;
userFactory.getData().success(function(data){
$scope.users = data;
}).error(function(error){
console.log(error);
})
});
but i can get the data, coul you help please.......
Angular encapsulate the api response in an object, try
userFactory.getData().success(function(response){ // response instead of data
$scope.users = response.data; // response.data instead of data
}).error(function(error){
console.log(error);
})
you can try the working plnkr here.
It does:
$resource(user.url)
To request for individual user for its data
result.push(userData)
Push to result and return to controller
userFactory.userData().then(function(data){
vm.userData = data;
});
We're using $resource here because we want to keep the reference to the data in the result array. Then after response come from server, our result array will reflect the changes and show in the view.
I am trying to get data back from a web service, I have to approaches the first is calling the data from the controller which works here is the code
$http({
method: 'POST',
url: 'https://url_json.php',
headers: {'Content-Type': 'application/x-www-form-urlencoded; charset-UTF-8'},
transformRequest: function(obj) {
var str = [];
for(var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
},
data: paramsVal
}).then(function(response){
$scope.myData = response.data.PlaceDetailsResponse.results[0].first_name;
console.log('my data',$scope.myData);
});
}
but I would like to share the data between controllers so I read service is the best options, so in my services.js I have:
.factory('userService', function($http){
return {
getUsers: function(){
return $http.post("https://url_json.php",
{entry : 'carlo' ,
type:'first_name',
mySecretCode : 'e8a53543fab6f00ebec85c535e'
}).then(function(response){
users = response;
return users;
});
}
}
})
but when I call it from the controller with var user = userService.getUsers(); returns the below in the console:
user is [object Object]
and inspecting element within chrome I only see:
user is Promise {$$state: Object}
Also in chrome when I drill down on Promise the data value = "".
Can anyone take a look at my services and see if I'm doing anything wrong.
Thanks
.then returns a promise. You're falling for the explicit promise construction antipattern.
getUsers: function(){
return $http.post("https://url_json.php",
{entry : 'carlo' ,
type:'first_name',
mySecretCode : 'e8a53543fab6f00ebec85c535e'
})
}
The above is all you need. Then, in your controller:
userService.getUsers()
.then(function(response) {
$scope.data = response.data; // or whatever
});
I would recommend looking at John Papa AngularJS style guide. He has a lot of information about fetching service data, using it in controllers, etc.
In your controller you will have to assign the user variable by resolving the promise return from the getUsers like below:
$scope.user = [];
$scope.error ="";
userService.getUsers().then(function(data){
$scope.user = data
},function(err){
$scope.error = err;
});
Hope this helps.
My service code look like belowed :-
data.service('SmartLearnerService', function ($http) {
//Get Single Records
this.get = function (id) {
return $http.get("/api/Category/");
}
});
Here is my controller code for App.js:-
$scope.questionlist = SmartLearnerService.get();
$scope.questionlist.then(function (pl) {
var res = pl.data;
$scope.que = res.QuestionLabel;
},
function (errorPl) {
console.log('failure loading Employee', errorPl);
});
console.log($scope.questionlist);
Here is Controller code for web api controller :-
public class CategoryController : ApiController
{
CommonDb db = new CommonDb();
public JsonResult Get()
{
var Result = db.GetQuestionById().ToList();
string message = "No Data Found";
if (Result.Count() != 0)
{
return new System.Web.Mvc.JsonResult()
{
Data = Result,
JsonRequestBehavior = System.Web.Mvc.JsonRequestBehavior.AllowGet
};
}
else
{
return new System.Web.Mvc.JsonResult()
{
Data = message,
JsonRequestBehavior = System.Web.Mvc.JsonRequestBehavior.AllowGet
};
}
}
}
}
And here is div tag where i want to bind questions from json result using ng-repeat directive.
<div class="question" align="center">{{Questions.QuestionLabel}}</div>
i am facing problem while binding json array in controller's $scope.questionlist and i am successfully getting json result from web api controller.
Ok, if I had to guess (and that's exactly what I'm doing), you want something like this in your controller...
SmartLearnerService.get().success(function(questions) {
$scope.questionList = questions;
});
or, if you're not a fan of the add-on success / error callbacks
SmartLearnerService.get().then(function(response) {
$scope.questionList = response.data;
});
and in your template
<div ng-repeat="question in questionList">
<div class="question" align="center">{{question.QuestionLabel}}</div>
<!-- and so on -->
</div>
This is totally assuming your C# controller returns JSON that looks something like...
[{
"QuestionID": "1",
"QuestionLabel": "Why are mirrors often slightly curved (convex) ?",
"Image": "zibra-crossing.jpg",
"Correct": "two",
"Explaination": "Question one explaination is goes here"
}, {
...
}]
Can you try this?
SmartLearnerService
.get()
.success(function (data, status) {
if (status === 200) {
//your code to process data is here
}else{alert(status)}
})
.error(function (data, status) {
//TODO: Use nice alert.
alert('Server request failed with status ' + status + ' while getting area in the ' + $item.Name);
});
You will get the status code that you are receiving and then you can change the code accordingly.
The approach that I took in my case was to serialize using JsonConvert from NewtonSoft and then return the string of Json object instead of Json object itself to improve the speed.
My code makes many AngularJS $http requests. Often it is 3-4 at the same time.
Is there some way that I can intercept the http messages so that I get just one alert pop up if the internet connectivity is lost and there are multiple requests going on? I have seen other sites that do this but then if the action requires a number of http calls it seems that I could get more than one error popup coming.
If possible I would like to do this in just the one place in my code.
You need add responseInterceptors inside you $httpProvider in configuration phase of angular. This interceptor gets called after angular $httpProvider processing the response.
CODE
module.config(['$httpProvider', function($httpProvider) {
var interceptor = ['$rootScope', '$q', '$location', function(scope, $q, $location) {
function success(response) {
return response;
}
function error(response) {
var status = response.status;
if (status == 500) {
alert("Internal Server Error")
return;
}
if (status == 404) {
alert("Page not found")
return;
}
// otherwise
return $q.reject(responseInterceptors);
}
return function(promise) {
return promise.then(success, error);
}
}];
$httpProvider.responseInterceptors.push(interceptor);
}]);
Above code will provide you better control on error handling when any request fails.
For more details refer this anwser.
Update
For showing alert only once we could create a service,if error occurred then that will handle the set error variable
Service
module.service('errorService',function(){
//getter
this.getErrorFlag = function(){
return this.isError;
}
//setter
this.setErrorFlag = function(val){
this.isError = val;
}
});
Interceptor
module.config(['$httpProvider', function($httpProvider) {
var interceptor = ['$rootScope', '$q', '$location','errorService', function(scope, $q, $location,errorService) {
function success(response) {
return response;
}
function error(response) {
//setting error variable
errorService.setErrorFlag(true)
return $q.reject(responseInterceptors);
}
return function(promise) {
return promise.then(success, error);
}
}];
$httpProvider.responseInterceptors.push(interceptor);
}]);
Inside you controller put all $http call promises inside $q.all, and when promises gets resolved then check for isError flag of errorService.
IsError flag will be true if error occurred at least one & by using it you can show error only once.
Controller
module.controller('appCtrl',['$scope','$q','errorService',function($scope,$q,errorService){
var ajax1 = $http.get('url').then(function(){
},
function(){
});
var ajax2 = $http.get('url').then(function(){
},
function(){
});
var ajax3 = $http.get('url').then(function(){
},
function(){
});
errorService.setErrorFlag(false);
$q.all(ajax1, ajax2, ajax3).then(function(data){
//check for isError flag from service
if(errorService.getErrorFlag())
alert('Error occurred while processing request.'); //this will show only once
else
alert('No error occurred while processing request.')
});
}]);
Hope this could help you.
Thanks.
If you don't want to use an interceptor, you could simply process the error callback of your $http calls:
$scope.httpError = null;
$scope.processHttpError = function() {
// If you don't already have got an http error
if (!$scope.httpError) {
$scope.httpError = "Cannot load stuff";
}
};
$http.get('/someUrl')
.success(function(data, status, headers, config) { ... })
.error($scope.processHttpError);
I am looking to have parameters in the route, by using a colon before the variable name
// dynamic pages for each ITEM, once selected
// from $routeParams.itemID in ItemCtrl
.when('/:itemID', {
templateUrl: 'views/item.html',
controller: 'ItemController'
})
When a div-box is clicked, Angular should route to the specific item
<div class="itemBox" ng-click="getItem(item._id)">
Right now, the call to the node/express API seems to be working
[16:36:18.108] GET http://localhost:8080/api/items/534240001d3066cc11000002 [HTTP/1.1 304 Not Modified 4ms]
But this error logs in the console:
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (http.js:691:11)
...
at Promise.<anonymous> (/Users/Username/Downloads/project/v19/app/routes.js:41:8)
...
Line 41 (for 41:8?) in routes.js is res.json(item);
// load the item model
var Item = require('./models/item');
// get One item
app.get('/api/items/:item_id', function(req, res) {
// use mongoose to get the one item from the database
Item.findById({
_id : req.params.item_id
},
function(err, item) {
// if there is an error retrieving, send the error. nothing after res.send(err) will execute
if (err)
res.send(err)
res.json(item); // return the item in JSON format
});
});
Though it seems like the issue might be in the Controller because all of the other API calls work.. And so I tried passing $routeParams all over the place!
angular.module('ItemCtrl', [])
// inject the Item service.factory into our controller
.controller('ItemController', function($scope, $routeParams, $http, Items, isEmptyObjectFilter) {
// get an Item after clicking it
$scope.getItem = function(id, $routeParams) {
Items.getOne(id, $routeParams)
// if successful getByID, call our function to get the Item data
.success(function(data, $routeParams) {
// assign our Item
$scope.item = data;
// for use with a parameter in appRoutes.js using itemID as the variable
$scope.itemID = $routeParams.itemID;
})
.error(function(data) {
console.log('Error: ' + data);
});
};
});
Or maybe it's the service? Does this need to pass $routeParams as function(id, $routeParams)
angular.module('ItemService', [])
// super simple service
// each function returns a promise object
.factory('Items', function($http) {
return {
get : function() {
return $http.get('/api/items');
},
getOne : function(id) {
return $http.get('/api/items/' + id);
},
create : function(itemData) {
return $http.post('/api/items', itemData);
},
delete : function(id) {
return $http.delete('/api/items/' + id);
}
}
});
Would really appreciate some assistance debugging this.. Thanks
It looks like you are getting the data correctly. The problem is that you want the route to change after successfully getting the API call?
$routeParams won't change the route for you. That just gets the data. Use $location to change the route.
.controller('ItemController', function($scope, $routeParams, $location, $http, Items, isEmptyObjectFilter) {
$scope.getItem = function(id) {
Items.getOne(id)
.success(function(data) {
$scope.item = data;
$scope.itemID = $routeParams.itemID;
// redirect
$location.path('/' + $routeParams.itemID);
});
});
});
Since all of your data seems to be ready to go, you just need Angular to redirect to the route. $location should be the way to go.
That message is because you are getting an error and executing the res.send() method, and after that you have res.json(), express is trying to respond twice.
Try changing:
if (err)
res.send(err)
To:
if (err) {
res.json({ error: err });
} else {
var object = item.toObject();
res.json(object);
}
Angular resource example:
angular.module('ItemService')
.factory('Items', ['$resource', function($resource) {
return $resource('/api/items/:itemID', {
itemID: '#_id'
}, {
update: {
method: 'PUT'
}
});
}]);
Now you can do this in your controller:
// Find
Items.get({
itemID: $routeParams.itemID
}, function(item) {
$scope.item = item;
});
// Update
$scope.item.name = 'New name';
$scope.item.$update();
// Remove
$scope.item.$remove();