Angularjs $http.get does not work - javascript

My purpose is to consume a REST web service in AngularJS and I am making some trials right now. Below code is not working and throwing following exception.
Can you help me identifty the problem?
Thanks in advance.
function getUsersFromLocal($scope,$http)
{
$http.get('http://localhost:8080/people').
success(function(data) {
$scope.data = data;
});
return data;
}
Error is: TypeError: Cannot read property 'get' of undefined
at getUsersFromLocal.
The service is accessible and I tested it through some REST clients.

Try like this , this way i found on w3school.
var app = angular.module('myApp4', []);
app.controller('customersCtrl', function($scope, $http) {
$http.get("http://www.w3schools.com/angular/customers.php")
.success(function(response) {
$scope.data= response.records;
});
});

If I understood correctly getUsersFromLocal function is inside controller, basically the function parameters are killing the $scope, $http object existence, You need to remove them from parameter & Also removed the return statement which was outside $http which won't work in anyways.
Code
app.controller('mainCtrl', function() {
$scope.getUsersFromLocal = function() {
$http.get('http://localhost:8080/people').
success(function(data) {
$scope.data = data;
});
};
$scope.getUsersFromLocal(); //call ajax method
});

if getUsersFromLocal is not a controller or service, and you are invoking this function manually, you should pass $http and $scope objects to it, like this
module.controller('TestController', function($scope, $http) {
function getUsersFromLocal($scope,$http) {
$http.get('http://localhost:8080/people').
success(function(data) {
$scope.data = data;
});
}
getUsersFromLocal($scope, $http); // pass this services manually
});

Related

how to start angular service (post, get and delete)

I generate a code with editor.swagger and I want to code a GUI with angular for that code. Since I'm newbie in angular, I dind't understand well how to start programming. I first decide to create 3 files : index.html, index.js and service.js.
Here is a part of my code :
I don't know if it's the good beginning or not. But the problem is that I don't have any idea how what I should do for POST and DELETE. Can you help me please?
You can do the standard 4 methods in Angluar JS(POST,GET,PUT,DELETE). To use these in angular you have to use the $http service that angular provides. To find out more about it check their documentation: https://docs.angularjs.org/api/ng/service/$http
From the Angular $http documentation:
Complete list of shortcut methods:
$http.get
$http.head
$http.post
$http.put
$http.delete
$http.jsonp
$http.patch
You can also use the method parameter in the $http service. So $http(method: 'DELETE', ...)
var app = angular.module('app');
app.service('apiService', ['$http', function($http){
this.get = function(){
return $http.get(URL);
};
this.delete = function(id){
return $http.delete(URL, id);
}
this.post = function(data){
return $http.post(URL, data);
}
}]);
app.controller('controller', ['$scope', 'apiService', function($scope, apiService){
var getData = apiService.get().success(function(){
});
}]);
You can use $resource and return it as a service.
app.factory('factoryResource', ['$resource', function($resource) {
var resource = {
getResource: function(context) {
var rsc = $resource(context, {}, {'update': {method: 'PUT'}});
return rsc;
}
};
return resource; }])
In your controller you should inject the newly created service as below:
app.controller('myCtrl', function($scope, factoryResource) {
$scope.resource = factoryResource.getResource('http://localhost:8080/api/v1/projects');
$scope.resource.save(object, successCallback, errorCallback); //post
$scope.resource.query(successCallback, errorCallback); //get all
$scope.resource.get({id: object.id}, successCallback, errorCallback); //get a specific object
$scope.resource.delete({id: object.id}, successCallback, errorCallback); //delete
}
Hope this helps;
Basically we have 4 method for a REST operation
Create (POST)-- To Create a new User (just for an example, it can be anything)
Read (GET) -- To get all users
Update (PUT) -- To update a user's property
Delete (DELETE) -- To delete a user
Let me know if you need further clarification.
In angular using service you can do that.
var app = angular.module('app', []);
app.factory('UserService', function($http){
var user = {};
user.post = function(data){
return $http.post('url', data);
}
user.get = function(){
return $http.get('url');
}
user.delete = function(id){
return $http.delete('url');
}
user.update = function(id, data){
return $http.put('url', data);
}
return user
});
app.controller('Controller', function('UserService'){
// Get
UserService.get().success(function(){
});
UserService.post(data).success(function(){
});
UserService.delete(id).success(function(){
});
UserService.get(id, data).success(function(){
});
})
This can be done easily through $resource, if you URL is proper rest.

Getting the object obtained from asynchronous $http service in angularJS to be accessible globally in $scope

I am working using Angular JS. I am trying to get a json object obtained using $http service to be accessible in a $scope variable. Inside all the asynchronous AJAX ($http.get()) calls, if I try to print the data obtained stored inside a $scope variable and print it, it works successfully and shows me the expected data. But outside scope of the asynchronous method, the same $scope variable assigned with data obtained loses hold of it and prints undefined.
Code:
var app = angular.module('chariot', ['ngRoute', 'ngFileUpload']);
app.factory('getTestcaseFactory', ['$http', '$routeParams', '$q', function($http, $routeParams, $q) {
return {
list: function(){
var deferred = $q.defer();
$http.get('/testcase/' + $routeParams.testcase)
.success(function(data, status, headers, config) {
deferred.resolve(data);
})
.error(function(data, status, headers, config) {
deferred.reject("Error fetching XML file: " + status + ' ' + JSON.stringify(headers));
});
return deferred.promise;
}
};
}
]);
app.controller('testcaseCapCtrl', ['$scope', '$routeParams', '$http', 'getTestcaseFactory', function($scope, $routeParams, $http, getTestcaseFactory) {
$scope.myjsonobj = '';
var fetchTestcaseDetails = function() {
getTestcaseFactory.list()
.then(
function(data) {
$scope.xml.file = data;
var x2js = new X2JS();
var jsonObj = x2js.xml_str2json($scope.xml.file);
$scope.xml.json = JSON.stringify(jsonObj, null, 2);
$scope.model = jsonObj;
console.log($scope.model);//PRINTS THE RIGHT DATA
},
function(data) {
alert(data);
});
}
fetchTestcaseDetails();
console.log($scope.model); //Prints undefined
}]);
By the time
console.log($scope.model);
executes, the $http request would have not gone through yet, and this is why it prints undefined. Once the $http request is done, your $scope.model will update accordingly. You can test this by using a $timeout
$timeout(function () {
console.log($scope.model);
}, 5000);
Don't forget to inject $timeout in your controller.
This saves my day! $timeout to the rescue. Thanks #Dan Moldovan for the answer! As the $http service is asynchronous, we have to set a timer to wait for a time interval till the point the data is really received in the promise.success section and then it can be assigned to a variable inside $scope.
var app = angular.module('chariot', ['ngRoute', 'ngFileUpload']);
app.factory('getTestcaseFactory', ['$http', '$routeParams', '$q', function($http, $routeParams, $q) {
return {
list: function(){
var deferred = $q.defer();
$http.get('/testcase/' + $routeParams.testcase)
.success(function(data, status, headers, config) {
deferred.resolve(data);
})
.error(function(data, status, headers, config) {
deferred.reject("Error fetching XML file: " + status + ' ' + JSON.stringify(headers));
});
return deferred.promise;
}
};
}
]);
app.controller('testcaseCapCtrl', ['$scope', '$routeParams', '$timeout', 'getTestcaseFactory', function($scope, $routeParams, $timeout, getTestcaseFactory) {
var fetchTestcaseDetails = function() {
getTestcaseFactory.list()
.then(
function(data) {
$scope.xml.file = data;
var x2js = new X2JS();
var jsonObj = x2js.xml_str2json($scope.xml.file);
$scope.xml.json = JSON.stringify(jsonObj, null, 2);
$scope.model = jsonObj;
console.log($scope.model);//PRINTS THE RIGHT DATA
},
function(data) {
alert(data);
});
}
fetchTestcaseDetails();
$timeout(function() {
console.log($scope.model); //Prints the Data now
}, 2000);
}]);
The solutions posted so far are fundemantally wrong, as they depend on an arbitrary timeout, and nothing guarantees that the async answer will be available by then.
As I suggested in a comment above, here are 2 more data/event-driven solutions.
You either only print in the callback function (which you're already doing in your example)
Or since you're using angular anyway, you can set up a watch (which in the background uses a not-too-nice dirty checking solution, but at least it's abstracted away from your code)
If you want to run a function called processData once the data is available, solution 1 you already do in your example, see this line:
console.log($scope.model);//PRINTS THE RIGHT DATA
Here you could call any other function to trigger the continuation of the process, just call whatever function:
console.log($scope.model);//PRINTS THE RIGHT DATA
processData();
Using angular's $watch mechanism (2.):
$scope.$watch(
function(){return $scope.model;},
function(newValue, oldValue){
if(newValue != null){
console.log($scope.model);
processData();
}
})
This will print the data when it is available after the async callback, and the program will continue with processing from then.

Aborting ngResource using a promise object

I've recently learned that ngResource request can be aborted either by specifying a timeout in ms or passing a deferred object.
The second solution does not seem to work for me, and I have no idea what I'm doing wrong. I've created a fiddle to demonstrate the problem http://jsfiddle.net/HB7LU/10977/
var myApp = angular.module('myApp',['ngResource']);
myApp.factory('myResource', function($resource) {
return {
getResource: function (aborter) {
var resource = $resource(
'http://api.openweathermap.org/data/2.5/weather?q=London,uk', {}, {
query: {
isArray: false,
timeout: aborter.promise
}
});
return resource;
}
};
});
myApp.controller('MyCtrl', function($scope, $q, $log, $timeout, myResource) {
var aborter = $q.defer();
setTimeout(function() {
$log.info('Aborting...');
aborter.resolve();
}, 10);
myResource.getResource(aborter).query().$promise.then(function(data) {
$scope.data = data;
});
});
I want to avoid sending multiple request at the time (I want to cancel the previous by calling aborter.resolve().
I was following this solution Angular $http : setting a promise on the 'timeout' config
Could you please advice me why it does not work?
It looks like it's an open issue with Angular 1.3: github.com/angular/angular.js/issues/9332 You're jsfiddle works if you drop back to 1.2.28.
Try using $timeout, instead of setTimeout, since that will take care of making sure your resolve is captured by angular $digest cycle.
myApp.controller('MyCtrl', function($scope, $q, $log, $timeout, myResource) {
var aborter = $q.defer();
$timeout(function() {
$log.info('Aborting...');
aborter.resolve();
}, 10);
myResource.getResource(aborter).query().$promise.then(function(data) {
$scope.data = data;
});
});
try to change this line of ngResource source code:
httpConfig[key] = copy(value);
in
httpConfig[key] = key !== 'timeout' ? copy(value) : value;
the problem is the copied promise

Calling JSON file from Angular Factory is not working

I am new in AngularJS. I was trying to call json file from factory function but it's showing my var customers = []; array is not updating. Please help.
Below is my code.
var demoApp = angular.module("myApp", []);
demoApp.factory('simpleFactory', ['$http', function($http){
return {
getCustomer: function(){
var customers = [];
return $http.get("http://www.w3schools.com/website/Customers_JSON.php")
.success(
function(data){
customers = data;
},
function(error){
console.log(error);
});
console.log(customers)
}
}
}]);
demoApp.controller("emplyCtrl", function($scope, simpleFactory){
$scope.customers = simpleFactory.getCustomer();
});
Demo Fiddle
Try something like this:
demoApp.factory('simpleFactory', ['$http', function($http){
return {
getCustomer: function(){
return $http.get("json/customers.json").then(
function(response){
var customers = [];
customers = response.data;
},
function(error){
console.log(error);
});
}
}
}]);
use this in your controller:
demoApp.controller("emplyCtrl", function($scope, simpleFactory){
simpleFactory.getCustomer().then(function(response){
$scope.customers = response.data;
});
});
Since the view (HTML) reads from the controller's $scope, you have to put the data in $scope somewhere in the controller. Setting it in the factory only allows access from within the factory.
Here is the working Fiddle
Hope this helps!
Don't you think that you should put "$" sign before http?
I think that the '$http' there should indicate that it is serializable. That is why, the $http should be stated in the parameter section the same way just like you mentioned in the previous string statement.
Additionally, you cannot just use http, since the syntax is to use $ in front of the http.
Otherwise, angular dll will not recognize your code.
demoApp.factory('simpleFactory', ['$http', function($http){
var customers = [];
$http.get("json/customers.json")
.success(function(data){
customers = data;
});
var factory = {};
factory.getCustomer = function(){
return customers;
};
return factory;
}]);
Take a look at the example here:
http://www.w3schools.com/angular/angular_http.asp
Thank you,

AngularJS 1.2 cross origin requests are only supported for HTTP

Is there any way to configure Angular app to make it available?
Im using a factory.
By the way, I'm using localhost as webserver but I'm making a request to other server (same network).
angular.module('demoApp.factories', [])
.factory('dataFactory', ['$http', function($http) {
var urlBase = 'external-server:8080';
var dataFactory = {};
dataFactory.getTest = function () {
return $http.get(urlBase + '/test');
};
return dataFactory;
}]);
Finally found the solution. Will post here, maybe it can help others:
angular.module('demoApp.factories', [])
.factory('dataFactory', ['$http', function($http) {
var urlBase = 'external-server:8080';
var dataFactory = {};
dataFactory.getTest = function () {
//Note the $http method changed and a new parameter is added (callback)
//the value of the callback parameter can be anything
return $http.jsonp(urlBase + '/test?callback=myCallback');
};
return dataFactory;
}]);
The controller file basically just calling this factory:
angular.module('demoApp.controllers', []).controller('controller1', ['$scope', 'dataFactory',
function ($scope, dataFactory) {
$scope.status;
$scope.data;
dataFactory.getTest().success(function (data)
{
$scope.data = data;
}).error(function (error)
{
$scope.status = 'Unable to load customer data: ' + error.message;
});
You may be looking to configure the $httpProvider as specified here: http://better-inter.net/enabling-cors-in-angular-js/
Another way is to create a simple http proxy on your front-end server to make external requests look like to angular that they're coming from the same server.

Categories