simple angular service confusion - javascript

To put it simply angular services always confuse me and I seem to get them working by trial and error. I'd like to know why in this case data returns undefined.
App module :
var app = angular.module('myApp', ['services']);
Service:
//creating a service module
var appServices = angular.module('services', []);
appServices.factory('Data', function(){
return {message : "I am data"}
});
Controller:
app.controller('firstCtrl',['Data',
function($scope, Data){
//get data from the service
$scope.data = Data;
console.log(Data);
}]);
app.controller('secondCtrl',['Data',
function($scope, Data){
//get data from the service
$scope.data = Data;
}]);
If I console log data I just get "undefined" .
Im just trying to do a simple example to return the object {message:"i am data"}
so that
$scope.data = Data;
then in the view
data.message = "i am data"
Would really appreciate an explanation of why this does not work. Thanks

You're not injecting $scope into the controller. Change it to this:
app.controller('firstCtrl', [
'$scope', // There should be an element of this array for each parameter
'Data',
function($scope, Data){
//get data from the service
$scope.data = Data;
console.log(Data);
}
]);
As you're only injecting the Data service it gets mapped to the $scope parameter of the controller function, and nothing gets mapped to the Data parameter (and since a variable that has not been assigned a value implicitly has the value undefined, you see undefined).

you can use above answer but you can use
app.controller('firstCtrl', function($scope, Data){
//get data from the service
$scope.data = Data;
console.log(Data);
});
this will work fine no need for passing array of services and function in controller as second argument just function will work fine.

Related

angularjs: passing a service into another service?

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) {

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

Getting dynamic data from Json to Html with Angularjs

var app = angular.module('myApp', ['ridge-speedometer']);
app.controller('customersCtrl', function($scope, $http, $timeout) {
$scope.getData = function(){
$http.get('asd.php').then(function (response) {
$scope.myData = 33; ////////// response.data
});
};
// Function to replicate setInterval using $timeout service.
$scope.intervalFunction = function(){
$timeout(function() {
$scope.getData();
$scope.intervalFunction();
}, 1000)
};
// Kick off the interval
$scope.intervalFunction();
Hi guys, as you see the codes above, I just have problem that line:
$scope.myData = 33;
$scope.myData = response.data"
when I'm writing 33 to the variable it works, but with "response.data". It isn't working. How can I get the value of my JSON.
This is my JSON page
[{"value":"23"}]
I have to get this 23
Thanks.
Try this code, You need to access the index[0] of the response
$scope.getData = function(){
$http.get('asd.php').then(function (response) {
$scope.myData = response.data[0].value;
});
Like this.You have JSON response
[{"value":"23"}]
Get value
$scope.myData = response[0].value;
See Demo
var response= '[{"value":"23"}]';
object = JSON.parse(response); //parses your json into object
console.log(object[0].value);
Try get it with response.data[0].value.
Maybe you have to JSON.parse(response.data)[0].value to get it.
In $http service calls , data response is usually in this format
I suggest you to get data like this
var response = response.data.data;
// now you can assign like you are doing
$scope.myData = response.value;
// or if your response is an array
$scope.myData = response[0].value;
I hope this helps. Thanks

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 Controller to update $scope automatically when backend data changes

I have a Service which uses $http to 'get' some JSON data from a REST API. The Controller uses the Service to get this data and initialise it in the $scope. How can I make it so that every time the JSON API changes that change is updated in the $scope, and thus the view?
Controller:
app.controller('MainController', function ($scope, BuildService) {
init();
function init() {
BuildService.getBuilds().then(function() {
$scope.builds = BuildService.data();
});
}
});
Service:
app.service('BuildService', function ($http, $q) {
var BuildService = {};
var deffered = $q.defer();
var data = [];
BuildService.getBuilds = function () {
//return builds;
$http.get('/api').
success(function(d, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
data = d;
deffered.resolve();
}).
error(function(d, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
deffered.reject();
});
return deffered.promise;
};
BuildService.data = function() { return data; };
return BuildService;
});
This question is not AngularJS-specific. What you want to achieve is a real-time app.
Method 1: polling
Use $interval to check JSON API every 30 seconds or so.
Method 2: WebSocket-based notification
If you have control over the JSON API, you can create another WebSocket-based notification API. Whenever JSON API changes, notify client to fetch JSON API again.
I'd say you really have too much unneccessary logic. Keep it simple and just go like that. If you want to reuse the GET you can do it in a getBuilds controller method.
app.controller('MainController', function ($scope, $http, BuildService) {
init();
function init() {
$http.get('/api').
success(function(data) {
$scope.builds = data;
});
}
});

Categories

Resources