Fetching data from a JSON object (from a given API) in AngulaJS - json

I have the following code to present data from a link (API) as suggestion for an autocomplete box. Although it is working for one link and not the other. I observed that data format for both are different, modified my code accordingly but it is still not helpful.
.js file:
var plunker= angular.module('plunker', ['ui.bootstrap', 'ngGrid']);
function TypeaheadCtrl($scope, $window, $http, limitToFilter) {
$scope.cities = function (cityName) {
return $http.jsonp("http://mtapi.azurewebsites.net/api/institute").then(function (response) {
return response[0].description;
});
};
}
HTML file:
<input type="text" id="depn" ng-model="formdata.department"
typeahead="suggestion.description for suggestion in cities($viewValue)"
placeholder="department" class="form-control">
If you replace the cities function with this one,
$scope.cities = function (cityName) {
return $http.jsonp("http://gd.geobytes.com/AutoCompleteCity?callback=JSON_CALLBACK &filter=US&q=" + cityName).then(function (response) {
return response.data;
});
};``
Even after I changed my code jsonP request to .get, it is still not working
var plunker= angular.module('plunker', ['ui.bootstrap', 'ngGrid']);
function TypeaheadCtrl($scope, $window, $http, limitToFilter) {
$scope.cities = function (cityName) {
return $http.get("http://mtapi.azurewebsites.net/api/institute").success(function(data) {
return data[0].description;
});
};
}
It is working fine.
Is there a problem with my code, or a back end server issue?

Change your cities function to use the data property of the response in your .then (that's how you'll access the response from a resolved HttpPromise):
var plunker= angular.module('plunker', ['ui.bootstrap', 'ngGrid']);
function TypeaheadCtrl($scope, $window, $http, limitToFilter) {
$scope.cities = function (cityName) {
return $http.get("http://mtapi.azurewebsites.net/api/institute").then(function (response) {
return response.data[0].description;
});
};
EDIT
Even making that code change won't solve your problem. This url does not support cross-origin requests, so you either need to host your angularjs app on the same domain and use a plain $http.get instead of $http.jsonp, or this url needs to support JSONP requests (the content-type of the response from this url is application/json. For JSONP to work it should be application/javascript).

I figured it out lately. Apart from the problem at back end there were issues in this code as well. I was returning the promise, but promise was never resolved to return the value also I was trying to return a string, whereas I should return array of strings. Here's the change:
$scope.aap = result.data;
var res = [];
res.push($scope.aap[0].Description);
return res;

Related

Login Service implementation in angularjs not working

This is my controller which is calling the login service
mod.controller("loginCtrl",function($scope,loginService,$http)
{
$scope.Userlogin = function()
{
var User = {
userid :$scope.uname,
pass:$scope.pass
};
var res = UserloginService(User);
console.log(res);
alert("login_succ");
}
});
And this is the login service code which takes the User variable and checks for username & password
mod.service("loginService",function($http,$q) {
UserloginService = function(User) {
var deffered = $q.defer();
$http({
method:'POST',
url:'http://localhost:8080/WebApplication4_1/login.htm',
data:User
}).then(function(data) {
deffered.resolve(data);
}).error(function(status) {
deffered.reject({
status:status
});
});
return deffered.promise;
// var response = $http({
//
// method:"post",
// url:"http://localhost:8080/WebApplication4_1/login.htm",
// data:JSON.stringify(User),
// dataType:"json"
// });
// return "Name";
}
});
I have created a rest api using springs which upon passing json return back the username and password in json like this
Console shows me this error for angular
You need to enable CORS for your application for guidance see this link
https://htet101.wordpress.com/2014/01/22/cors-with-angularjs-and-spring-rest/
I prefer to use Factory to do what you're trying to do, which would be something like this:
MyApp.factory('MyService', ["$http", function($http) {
var urlBase = "http://localhost:3000";
return {
getRecent: function(numberOfItems) {
return $http.get(urlBase+"/things/recent?limit="+numberOfItems);
},
getSomethingElse: function(url) {
return $http.get(urlBase+"/other/things")
},
search: function (searchTerms) {
return $http.get(urlBase+"/search?q="+searchTerms);
}
}
}]);
And then in your controller you can import MyService and then use it in this way:
MyService.getRecent(10).then(function(res) {
$scope.things = res.data;
});
This is a great way to handle it, because you're putting the .then in your controller and you are able to control the state of the UI during a loading state if you'd like, like this:
// initialize the loading var, set to false
$scope.loading = false;
// create a reuseable update function, and inside use a promise for the ajax call,
// which is running inside the `Factory`
$scope.updateList = function() {
$scope.loading = true;
MyService.getRecent(10).then(function(res) {
$scope.loading = false;
$scope.things = res.data;
});
};
$scope.updateList();
The error in the console shows two issues with your code:
CORS is not enabled in your api. To fix this you need to enable CORS using Access-Control-Allow-Origin header to your rest api.
Unhandled rejection error, as the way you are handling errors with '.error()' method is deprecated.
'Promise.error()' method is deprecated according to this and this commit in Angular js github repo.
Hence you need to change the way you are handling errors as shown below :
$http().then(successCallback, errorCallback);
function successCallback (res) {
return res;
}
function errorCallback (err) {
return err;
}
One more thing in your code which can be avoided is you have defined a new promise and resolving it using $q methods, which is not required. $http itself returns a promise by default, which you need not define again inside it to use it as a Promise. You can directly use $http.then().

Consuming JSON string array, returned by a webservice, in AngularJS

There is a Webservice that is returning a json object in below format:
["Brazil","Argentina","Chile"]
(this json object has been parsed by Online JSON parsers, which proves it is a proper json object)
In AngularJS, I wrote the below code to consume the WebService.
app.factory('webServiceFactory', ['$http', function ($http) {
return $http.get('http://SomeWebService/api/anOperation')
.success(function (data) {
return data;
})
.error(function (err) {
return err;
});
}]);
When I call this in my controller, the success part is never hit and, instead, the error part is executed. That means there is some error calling the web-service. I think it has to do something with the JSON object that is being returned.
Edit 1: The Controller code
app.controller('mainController', ['$scope', 'webServiceFactory', function ($scope, webServiceFactory) {
webServiceFactory.success(function (data) {
$scope.Countries = data;
});
}]);
Edit 2: Localhost & CORS
When I hosted the service in my local IIS and consumed it using localhost, it worked. That means there is no error in consuming the JSON String array.
However, when I use a Fully qualified name or machine name, the FireFox indicates CORS header missing 'Access-Control-Allow-Origin'.
This might lead to another question, as to how to make it CORS compatible. However, the main question is closed.
So, my question, is How do I consume a web-service in AngularJS that returns just an array of strings with no Key/Value pair?
Thanks
maybe you are doing a request to a service in other domain; that is not possible since exists the "same origin policy" https://www.w3.org/Security/wiki/Same_Origin_Policy
app.factory('webServiceFactory', ['$http', function ($http) {
return
{
getCountries: function(callback){
$http.get('http://SomeWebService/api/anOperation').then(function(reponse){
callback(response.data);
});
}
};
}]);
Then in your controller
webServiceFactory.getCountries(function(countries){
$scope.countries = countries;
});

Angular factory does not return array of objects but a single object

I am new to angular and I am trying to load a CSV list inside a factory and then convert it to json. I am using Papaparse (CSV to json library) inside the factory. When I console log the factory I get the array of objects which is exactly what I want but when I pass it inside my controller I get a single object which holds all the data.
This is my factory
(function() {
var app = angular.module('test');
app.factory('testFactory', ['$http', function($http) {
var url = 'my-list.csv';
var getContact = function() {
return $http.get(url).success(function(data) {
Papa.parse(data, {
header: true,
complete: function(results) {
console.log(results.data);
return results.data;
}
});
});
};
return {
getContact: getContact
};
}]);
}());
And this is my controller
(function() {
var app = angular.module('test');
app.controller('testCtrl', ['$scope', 'testFactory', function($scope, testFactory) {
testFactory.getContact().then(function(data) {
$scope.contacts = data;
console.log(data);
});
}]);
}());
I want be able to do something like this inside my view
{{ contact.firstname }}
The issue is the order of resolution. Inspecting the console statements shows that you're assigning $scope.contacts to the resolution of the $http.get promise, and not the actual parsing.
Instead of returning the $http.get promise, return a deferred promise and resolve at the end of parsing:
var parsePromise = $q.defer();
$http.get(url).success(function(data) {
Papa.parse(data, {
header: true,
complete: function(results) {
console.log(results.data);
parsePromise.resolve(results.data);
}
});
});
return parsePromise.promise;
See working demo here.
Update: As per the comments, you could use .then to chain promises instead of creating a new deferred. The plunkr has both, you can use the changelog to toggle methods.

Angularjs $resource and $http synchronous call?

I want write two services one with a $http.get method and one with $resource
This service should receive a Json Object and looks like this, at the moment this code is direct in my controller and not in a service:
var csvPromise= $http.get(base_url + 'DataSource/1').success(function(data) {
$scope.data4=JSON.stringify(data);
});
The problem is, I want save received data in $scope.data4 and I want use this data after the $http.get call but the value is empty.
Direct after this call there is and Object that needs this value:
new myObject($scope.data4)
so myObject must wait so long until the data has arrived.
or can I make a synchronous call with $http or $resource ?
How can i do this ? I have found so many examples with promise and .then but nothing has worked for me.
EDIT: I have now written a service but it didn`t work:
var test=angular.module('myApp.getCSV', ['ngResource']);
test.factory('getCSV',function($log, $http,$q, $resource){
return {
getData: function (id) {
var csvPromise= $http.get(base_url +'DataSource/'+id)
.success(function(data) {
return data;
});
return csvPromise;
}
}
});
and then in my controller I call this:
getCSV.getData(1).then(function(theData){
$scope.data4=JSON.stringify(theData);
new myObject( $scope.data4); });
but this did not work. I thought if the $http.get receives the data then the then Function is called.
I don't believe you can do synchronous calls. That said, you have at least two options:
1) Pass in the data using the $routeProvider resolve feature. From the documentation:
An optional map of dependencies which should be injected into the controller. If any of these dependencies are promises, the router will wait for them all to be resolved or one to be rejected before the controller is instantiated. If all the promises are resolved successfully, the values of the resolved promises are injected
An example on how to use this:
$routeProvider
.when('/your/path', {
templateUrl: '/app/yourtemplate.html',
controller: 'yourController',
resolve: {
data: ['$route', '$http', function($route, $http) {
return $http.get(base_url +'DataSource/1');
}]
}
})
And then in your controller:
app.controller('yourController', ['$scope', 'data', function($scope, data) {
$scope.data4 = JSON.stringufy(data);
var yourObj = new myObject($scope.data4);
}]);
2) The second option is to use promises and only instantiate your new myObject($scope.data4) once the promise successfully completes.
Your code needs to be changed just a bit:
$scope.data4 = '';
var csvPromise= $http.get(base_url +'DataSource/1');
csvPromise.then(function(data){
$scope.data4 = JSON.stringify(data);
}, function(data){
//error handling should go here
window.alert(data);
});
This should give you what it sounds to me like you need.
As i know, there's no way to sync~ call the http or resource. They're hard coded on AngularJS core file :
xhr.open(method, url, true);
And you don't want to hurt your users too by blocking the browser wait the data arrived. You'll better show how you make the nothing has worked for me so we can start working to fix it.
Have you try call new myObject($scope.data4) inside success method?
$http.get(...).success(function(data){
$scope.data4 = JSON.stringify(data); // I've no idea why do you need this.
var stuff = new myObject($scope.data4); // THis is now your.
});

view not gathering data from service through controller

Having trouble loading an external json file and having it's contents display on my view. I've included my view, controller and services code. What do I need to change?
view.html
<div ng-controller='BaseCtrl'>
<table class="table table-hover">
<tbody>
<tr class="tr-sep" ng-repeat="example in examples" ng-click="showUser(example)">
<td>{{example.name}}</td>
<td>{{example.type}}</td>
<td>{{example.size}}</td>
</tr>
</tbody>
</table>
</div>
controller.js
'use strict';
angular.module('projyApp')
.controller('BaseCtrl', function ($scope, data) {
$scope.examples = data.getAllExamples();
$scope.showUser = function(example) {
window.location = '#/user/' +example.size;
};
});
service.js
'use strict';
angular.module('projyApp')
.service('data', function data() {
var examples;
var getAllExamples = function () {
$http.get("../../TestData/Examples.json").success($scope.examples = data.examples);
};
});
Your service code isn't correct. I see the following problems:
You're creating a local variable getAllExamples that's not accessible from outside the service;
You're using the $http service, but that dependency isn't expressed in the service constructor;
You're trying to update the scope from the service, but it's inaccessible from there. Plus, the $scope variable is not even defined inside the service code.
Here's how your service could look like:
.service('data', function($http) {
this.getAllExamples = function(callback) {
$http.get("../../TestData/Examples.json")
.success(function(data) {
if (callback) callback(data.examples);
});
};
});
And your controller code would be like this:
.controller('BaseCtrl', function ($scope, data) {
data.getAllExamples(function(examples) {
$scope.examples = examples;
});
$scope.showUser = function(example) {
window.location = '#/user/' +example.size;
};
});
You could ditch the callback in the getAllExamples function and work directly with the $http.getreturned promise, but that's a bit more complicated.
Update Added a Plunker script to illustrate the code above.
Main module definition should look like:
angular.module("projyApp",[/*dependencies go here*/]);
Service should look like
//this use of module function retrieves the module
//Note from comments in angular doc: This documentation should warn that "angular.module('myModule', [])" always creates a new module, but "angular.module('myModule')" always retrieves an existing reference.)
angular.module('projyApp')
.service('dataService', [/*dependencies,*/function() {
var service = {
examples:[],
getAllExamples = function () {
$http.get("../../TestData/Examples.json").success(function(returnedData){examples = returnedData});
}
}
return service;
});
Controller should look like:
angular.module('projyApp')
.controller('BaseCtrl', function ($scope, dataService) {
$scope.examples = [];
$scope.showUser = function(example) {
window.location = '#/user/' +example.size;
};
$scope.$watch(function(){return dataService.examples}, function(newVal,oldVal) {$scope.examples = newVal});
});
Also you can add
debugger;
on an line to trigger Chrome to break (like a breakpoint but without having to dig through the scripts at run-time) so long as the Debugging Panel is open (F12)
You should use a callback instead of assigning in to a scope in you data service. By doing that, you can use this function in multiple controllers an assign values to appropriate scopes.
Data Service
var getAllExamples = function (callback) {
$http.get("../../TestData/Examples.json").success(function(data) {
if (typeof callback === "function") callback(data);
});
};
Controller
data.getAllExemples(function(data) {
$scope.examples = data;
});
EDIT
Another what is to create a promise object.
Data Service
var getAllExamples = function () {
return $http.get("../../TestData/Examples.json");
};
Controller
var promise = data.getAllExemples();
promise.then(function(data) {
$scope.examples = data;
});
EDIT 2
In your service, you need to return your functions
angular.module('projyApp')
.service('data', function data() {
var examples;
return {
getAllExamples: function () {
$http.get("../../TestData/Examples.json").success(...);
}
};
});