angularjs: passing a service into another service? - javascript

I am trying to sort out the best way to do the following:
At the request of our backend developer we want to have a json file that contains a master list of the api urls that are used in requests by my frontend. This way the end user's browser only makes one request for the object and we can then pass them this into other services. so for example...
the dataUrl JSON contains the following
{
"emails":"json/emails.json",
"mapping":"json/mapping.json",
"profile":"json/profile.json"
}
and I would need to store that as a variable that could be used in all of my api calls like such:
app.factory('Emails', ['$http', function($http, Urls) {
var url = ""; //something here to get the dataUrl object for "emails"
var query = {};
query.getItems = function () {
return $http.get(url.emails); //from var emails above?
};
return query;
}]);
What is going to be my best approach to this?
This is what I tried so far and it didn't work...
app.factory('Urls', ['$http', function($http) {
var query = {};
query.getItems = function () {
return $http.get('json/dataUrls.json');
};
return query;
}]);
app.factory('Emails', ['$http', function($http, Urls) {
Urls.getItems().then(function(response) {
var url = response.data.emails;
console.log(url);
})
var query = {};
query.getItems = function () {
return $http.get('json/emails.json');
};
return query;
}]);
This results in a console error TypeError: Cannot read property 'getItems' of undefined

You are injecting dependency in wrong way
First inject it then create it's instance
Try this
Replace
app.factory('Emails', ['$http', function($http, Urls) {
to
app.factory('Emails', ['$http', 'Urls', function($http, Urls) {

Related

AngularJS: Unable to Send $Http JSON Response to View

Trying to get JSON data from an API and show the result in a view using AngularJS. I'm able to get the data correctly but unable to show it in the view.
When i try to access the object's data the result is always undefined.
Here's what i'm doing...
API Service:
myApp.service('apiService', ['$http', function($http)
{
var api = "http://domain.xpto/api/";
var self = this;
this.result;
var apiService =
{
getSection: function(id)
{
var url = api + "section/" + id;
return $http.get(url);
}
}
return apiService;
}]);
Controller:
myApp.controller('mainController', ['$scope', '$routeParams', 'apiService', function($scope, $routeParams, apiService)
{
apiService.getSection(1).then(function(response)
{
$scope.$applyAsync(function ()
{
var data = response.data; //json data as expected
var section = data.section; //undefined?!
var images = data.images; //undefined!?
$scope.title = section.title; //undefined!?
});
});
}]);
JSON Result:
UPDATE: Simplified my apiService based on #Salih's and #elclanrs's suggestion.
Why am i unable to access the inner objects of the json (f.e, data.section.title)?
UPDATE #2: I'm finally able to access the data. It seems i needed an extra data level to get access to the section object of my json array (response.data.data.section). Honesty i don't understand why. I've accessed the API using jquery and it was strait forward...
Edit: I made this plunker to help you!
http://embed.plnkr.co/Yiz9TvVR4Wcf3dLKz0H9/
If I were you, I would use the service function to update the own service value. You already created this.result, you can just update its value.
Your Service:
myApp.service('apiService', ['$http', function($http)
{
var api = "http://domain.xpto/api/";
var self = this;
this.result = {};
this.getSection = function(id){
var url = api + "section/" + id;
$http.get(url).then(function(res){
self.result = res;
});
}
}]);
I wouldn't use a Promise for this case. You can access the Service's var into your Controller and View.
Your controller:
myApp.controller('mainController', ['$scope', '$routeParams', 'apiService',
function($scope, $routeParams, apiService)
{
$scope.apiSer = apiService;
$scope.apiSer.getSection(1);
}]);
In your View:
<pre>{{ apiSer.result }}</pre>
And now you'll see your parameter get updated in real time.
In your getSection function just write and return the following
return $http.get(url);
You might need to use angular.forEach method to parse your inner values of the JSON . Take a look at this example Accesing nested JSON with AngularJS

Angularjs Flickr API SyntaxError: Unexpected token when using nojsoncallback=1

I have an angularjs app to call a flickr api.
I want the data in RAW json format with no function wrapper and as per the docs, applying &nojsoncallback=1 .
However I'm getting the following console error. SyntaxError: Unexpected token '
This error only appears when applying &nojsoncallback=1 to the url. However I want RAW json with no wrapper.
If I don't apply the above to the url and simple use https://api.flickr.com/services/feeds/photos_public.gne?tags=trees&format=json I get no error, but when console logging out the typeof I get 'string' displayed.
I then try parsing this into JSON and get another error because it has a wrapped. Hence why I want RAW.
Below is the code I have so far. Any help - much appreciated.
JS
(function(){
'use strict';
var app = angular.module('flickrApp', []);
app.controller('FlickrFeedController', ['$http', '$scope', function($http, $scope){
// grab the flickr api
var response = $http.get('http://crossorigin.me/https://api.flickr.com/services/feeds/photos_public.gne?tags=trees&format=json&nojsoncallback=1');
// on success
response.success(function(data){
// console logging out the typeof gives 'string'
console.log(typeof(data));
// since it's a string I would then want to convert it into a json object
// but I need to sort the current error out first
// data = JSON.parse(data);
// console.log(typeof(data));
});
}]);
})();
EDIT:
This is a work around removing &nojsoncallback=1 from the url (removing the console error) and since the data comes back as a string having to replace characters, then parse. Not great but I get the required output (object) and thought I'd add it up here for others to view.
JS
(function(){
'use strict';
var app = angular.module('flickrApp', []);
app.controller('FlickrFeedController', ['$http', '$scope', function($http, $scope){
// grab the flickr api
var response = $http.get('http://crossorigin.me/https://api.flickr.com/services/feeds/photos_public.gne?tags=trees&format=json');
// on success
response.success(function(data){
// typeOf is 'string' even though format=json is specified in the url
//console.log(typeof(data));
//console.log(data);
// work-around since data is returned as a string
data = data.replace('jsonFlickrFeed(', '');
data = data.replace('})', '}');
data = data.replace(/\\'/g, "'");
// parse the data
data = JSON.parse(data);
// typeOf is 'object'
console.log(data.items);
console.log(typeof(data));
});
}]);
})();
Generate angular resource to call the api with format: {'json', jsoncallback: 'JSON_CALLBACK'}. Check complete solution here - http://plnkr.co/edit/Lxxkb9?p=preview
var app = angular.module('flickrApp', ['ngResource']);
app.factory('Flickr', function($resource, $q) {
var photosPublic = $resource('http://crossorigin.me/https://api.flickr.com/services/feeds/photos_public.gne?tags=trees&format=json',
{ format: 'json', jsoncallback: 'JSON_CALLBACK' },
{ 'load': { 'method': 'JSONP' } });
return {
get: function() {
var q = $q.defer();
photosPublic.load(function(resp) {
q.resolve(resp);
console.log(resp.items);
})
return q.promise;
}
}
});
app.controller('FlickrCtrl', function($scope, Flickr) {
Flickr.get();
});

Using Node/Angular, how do I make a call to an api (using methods from a node module) and have the data sent to the scope?

I am trying to use angular + node and am making a method call to a JS Api.
It returns data in my index.js file that I want to be made available in my angular module for attachment to the $scope.
My two approaches/attempts have been to:
1) Inject the hiw-api module as a factory parameter (won't work/how do won't pick up my module.
2) Use RequireJS to include node module hiw-api (too complex)
My goal is that once the data is in the $scope I can manipulate it, I just can't seem to get it there. Any help would be greatly appreciated! index.js Github, index.html (if you dare)
var hiw = require("hiw-api");
var apiKey = "da45e11d07eb4ec8950afe79a0d76feb";
var api = new hiw.API(apiKey);
var http = require("http");
exports.index2 = function (req, res) {
var rawresponse;
var founderror;
var indicatorDescription;
var locales;
//var allinidcatorsURL = '/Indicators/ { page }?Key= { key }';
//var filter = new hiw.Filter()
// .addEqual(hiw.Locale.Fields.ScriptFullName, "Arkansas");
hiw.Synchronizer.sync([
hiw.IndicatorDescription.getByID(279, api, function (data, response, error) {
indicatorDescription = data;
console.log(indicatorDescription.fullDescription);
console.log(indicatorDescription);
title = "Express"; //response: rawresponse, error: founderror
}),
hiw.Locale.getAll(api, function (data, response, error) {
locales = data; //Array of Locale
//console.log(locales);
})
], function (data) {
res.sendfile('./views/index.html');
//res.json(locales);
});
};
Assuming you have the HIWmethods defined as a service correctly, you have to inject it in the controller like this:
.controller('mainController', ['$scope', 'HIWmethods', function($scope, HIWmethods) {
$scope.formData = {};
$scope.loading = true;
// GET =====================================================================
// when landing on the page, get all todos and show them
// use the service to get all the todos
$scope.test = "Hello world!!!!!!!!!!"
HIWmethods.getLocales().then(function(data) {
$scope.locales = {
availableOptions: data
}
$scope.loading = false;
});
}]);

Displaying JSON Data In <Select> Using AngularJS (Error)

I am having an issue with displaying JSON data that I am getting passed to display in a html control.
I have set-up module which all looks correct and fine:
//Define an angular module for our app
var AngularJSTest = angular.module('AngularJSTest', ['ui.router']);
//Define Routing for the application
AngularJSTest.config(['$stateProvider', '$urlRouterProvider',
function ($stateProvider, $urlRouterProvider) {
$stateProvider.
state('home', {
name: 'home',
templateUrl: 'AngularJSTestPage.html',
controller: 'AngularJSTestPageCtrl'
})
}]);
Then in my controller I am getting my JSON data and storing in testAccounts:
AngularJSTest.controller("AngularJSTestPageCtrl", ["$scope", "$http", function ($scope, $http) {
$http.get('http://localhost:53215/IBookService.svc/GetBooksList').success(function (data) {
$scope.testAccounts = data;
$scope.selectedTestAccount = $scope.testAccounts[0];
});
}]);
I have tested that my results are coming back as I wrote:
Console.log($scope.testAccounts);
This returned all my JSON which looks like the following:
[{"BookName":"test1","ID":1},{"BookName":"test2","ID":2},{"BookName":"test","ID":3}]
Finally, in my html I am using 'ng-options' and selecting all the 'BookName' from my JSON data:
<body ng-app="AngularJSTest">
<div ng-controller="AngularJSTestPageCtrl">
<select class="form-control" data-ng-model="selectedTestAccount" data-ng-options="item.BookName for item in testAccounts">
<option label="-- ANY --"></option>
</select>
</div>
Error
The error happens when I load up my project the control shows a list of 84 labels which say 'undefined'.
Anyone have any idea why this might be happening?
EDIT
Here is what the URL returns:
JSON Image
EDIT 2
I am getting my data from WCF Service like below, is this incorrect?
public List<DC_BOOK> Books()
{
List<DC_BOOK> listBook = new List<DC_BOOK>();
DC_BOOK books = new DC_BOOK();
books.ID = 1;
books.BookName = "test1";
listBook.Add(books);
DC_BOOK books1 = new DC_BOOK();
books1.ID = 2;
books1.BookName = "test2";
listBook.Add(books1);
DC_BOOK books2 = new DC_BOOK();
books2.ID = 3;
books2.BookName = "test";
listBook.Add(books2);
return listBook;
}
public string GetBooksList()
{
using (SampleDbEntities entities = new SampleDbEntities())
{
// Serialize the results as JSON
DataContractJsonSerializer serializer = new DataContractJsonSerializer(Books().GetType());
MemoryStream memoryStream = new MemoryStream();
serializer.WriteObject(memoryStream, Books());
// Return the results serialized as JSON
string json = Encoding.Default.GetString(memoryStream.ToArray());
return json;
//return entities.Books.ToList();
}
}
As you say, the returned string is exactly 84 characters long and you are getting 84 undefined errors. It seems that your svc isn't returning proper JSON headers and hence the returned JSON string is being treated as an array of 84 elements.
Try this:
AngularJSTest.controller("AngularJSTestPageCtrl", ["$scope", "$http", function ($scope, $http) {
$http.get('http://localhost:53215/IBookService.svc/GetBooksList').success(function (data) {
$scope.testAccounts = JSON.parse(data);
$scope.selectedTestAccount = $scope.testAccounts[0];
});
}]);
So after building out this example I didn't have an issue with box not loading the data correctly.
the only thing that i changed was the way the variable on the scope was being assigned
$scope.testAccounts = data;
$scope.selectedTestAccount = data[0];
Here is my plnkr

AngularJS Service for XHR

I am trying to create a service in AngularJS which would fetch me JSON data from a website.
I wrapped the service in a factory method as shown below
App.factory('httpService', function($http) {
delete $http.defaults.headers.common['X-Requested-With'];
return {
getData : function() {
var url = "http://www.reddit.com/.json?callback=JSON_CALLBACK";
return $http.jsonp(url).then(
function(result) {
return result;
});
}
}
});
The problem I'm coming across is that I receive an error Uncaught SyntaxError: Unexpected token :. When I use get() instead of json() I get a 501/CORS error.
The URLs from where I am trying to fetch the data are:
http://api.4chan.org/b/1.json
http://www.reddit.com/.json
following is a link to my jsfiddle with the rest of the code.
http://jsfiddle.net/fatgamer85/adPue/3/
Does any one has any idea on how to solve this?
EDIT: I have managed to get the data and solved the issue. Thanks to sza
Following is the code which I've used if anyone's interested
var myApp = angular.module("client", []);
myApp.factory('myXHRService', function($http) {
delete $http.defaults.headers.common['X-Requested-With'];
return {
getData : function(url) {
return $http.jsonp(url).then(
function(result) {
return result.data;
}
);
}
}
});
myApp.controller('MainCtrl', function($scope, myXHRService) {
$scope.xhrData = {};
$scope.data = {};
$scope.url = "http://www.reddit.com/.json?jsonp=JSON_CALLBACK";
myXHRService.getData($scope.url).then(function(data) {
var xhrData = angular.fromJson(data);
$scope.xhrData = xhrData.data.children;
});
});
myApp.config(function($httpProvider){
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
});
The main difference here is the callback in URL parameters jsonp apart from that, everything works fine and dandy.
I think it may relate to API endpoint issue of Reddit.com. If you try this API, it will work using jsonp
var url = "http://www.reddit.com/top.json?jsonp=JSON_CALLBACK";
For the API /.json, I suggest you implement the server side code to retrieve data though it returns valid JSON but somehow can't be accessed correctly across domain.

Categories

Resources