AngularJS factory dependencies - javascript

I'm using AngularJS to extract information stored in mongodb. I'm trying to use a factory to retrieve that information using $http . I read so much information about how to do it, and no one works for me.
Also I'm using node + express, the routes works fine. The problem is the factory and the dependencies.
The only thing I need is:
Extract information stored in mongodb.
Store that information in a controller.
Show that information in the main page of my app.
index.html
<!doctype html>
<html ng-app="angular-blog">
<head>
<title> Angular blog </title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- AngularJS and JQuery include. -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.1/angular.min.js"></script>
<!-- Custom CSS -->
<link rel="stylesheet" href="./css/article.css" ></link>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"></link>
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css"></link>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</head>
<body>
<menu-bar></menu-bar>
<div class="container" ng-controller="ArticleController as articleCtrl">
<h2> Blog </h2>
<div class="col-sm-4" ng-repeat="elem in articleCtrl.list">
<h4>{{ elem.title }}</h4>
<p> {{ elem.desc }} </p>
</div>
</div>
<!-- Custom controller. -->
<script src="./js/controllers/article.js"></script>
</body>
</html>
article.js
(function (){
var app = angular.module ('angular-blog', []);
app.directive ('menuBar', function (){
return {
restrict : 'E',
templateUrl : '../templates/menu-bar.html'
};
});
app.service ('articleFactory', ['$q', '$http', function ($q, $http){
this.getAllArticles = function (){
var deferred = $q.defer(),
httpPromise = $http.get ('/entries');
httpPromise.success (function (data){
deferred.resolve (data);
})
.error (function (err){
console.log (err);
});
return deferred.promise;
}
}]);
app.controller ('ArticleController', ['$http', 'articleFactory', function ($http, articleFactory){
this.article = {}; // Simple article.
this.list = []; // Article list.
this.list = articleFactory.getAllArticles()
.then (function (data){
return data;
}, function (err){
console.error (err);
});
this.addArticle = function (){
$http.post ('/addEntry', this.article)
.success (function (data){
console.log (data);
})
.error (function (data){
console.log ('Error: ' + data);
});
this.article = {};
};
this.resetArticle = function (){
this.article = {};
};
}]);
})();
Error
My main page doesn't show the list.

DOCS
Change your factory to service as you are using this factory return an object or primitive type not bind with this
app.services('articleFactory', ['$q', '$http', function ($q, $http){
this.getAllArticles = function (){
var deferred = $q.defer(),
httpPromise = $http.get ('/entries');
httpPromise.success (function (data){
deferred.resolve (data);
})
.error (function (err){
console.log (err);
});
return deferred.promise;
}
}]);
UPDATED ANSWER
Your controller should be like this:-
app.controller ('ArticleController', ['$http', 'articleFactory', function ($http, articleFactory){
this.article = {}; // Simple article.
this.list = []; // Article list.
articleFactory.getAllArticles()
.then (function (data){
this.list = data;
}, function (err){
console.error (err);
});
this.addArticle = function (){
$http.post ('/addEntry', this.article)
.success (function (data){
console.log (data);
})
.error (function (data){
console.log ('Error: ' + data);
});
this.article = {};
};
this.resetArticle = function (){
this.article = {};
};

Related

MVC Controller method call from Angularjs return View HTML instead of JSON result

I have the following Controller method under HomeController,
[HttpGet]
public ActionResult GetStudents()
{
Student std1 = new Student();
List<Student> stdlst = new List<Student>();
std1.Id = 1;
std1.Name = "Emmanuvel";
std1.Age = 25;
stdlst.Add(std1);
Student std2 = new Student();
std2.Id = 2;
std2.Name = "Michael";
std2.Age = 24;
stdlst.Add(std2);
Student std3 = new Student();
std3.Id = 3;
std3.Name = "Hannah";
std3.Age = 22;
stdlst.Add(std3);
return Json(stdlst, JsonRequestBehavior.AllowGet);
}
And I'm calling this method using Angularjs Ajax function as below,
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular.min.js"></script>
<script type="text/javascript">
var app = angular.module('MyApp', [])
app.controller('MyController', function ($scope, $http, $window) {
$scope.ButtonClick = function () {
$http.get('#Url.Action("GetStudents","Home")')
.success(function (data) {
$scope.students = data;
console.log($scope.students);
})
.error(function (data) {
console.log(data);
});
}
});
</script>
unfortunately, the console.log printing the View Page's HTML code, instead of the JSON data. Here is the console.log output,
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width"/>
<title>Index</title>
</head>
<body>
<div ng-app="MyApp" ng-controller="MyController">
<input type="button" value="Submit" ng-click="ButtonClick()"/>
</div>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular.min.js"></script>
<script type="text/javascript">
var app = angular.module('MyApp', [])
app.controller('MyController', function ($scope, $http, $window) {
$scope.ButtonClick = function () {
$http.get('/Home/GetStudents')
.success(function (data) {
$scope.students = data;
console.log($scope.students);
})
.error(function (data) {
console.log(data);
});
}
});
</script>
</body>
</html>
Help me to understand the wrong I did in this code.
there are a number of changes I would do there.
First separate the angular code from your view. You probably did it to be able to use the Razor syntax to build the URL but now you have a dependency on that.
What I would do is this :
move the angular controller into it's own file.
change the JavaScript URL to '/Home/GetStudents'
change the return type of your backend controller to JsonResult, instead of ActionResult. Even if you are passing Json in the result, because it's ActionResult, it will still come back with the HTML of the page.
Once you do all this, first check in the browser that you are receiving the proper data by calling the '/Home/GetStudents' URL yourself. Once you are sure, then add some breakpoints and make sure Angular is receing the data properly and then continue from there.

using factory in the controller return undefined

I am trying to send value from my view to the controller using function inside ng-click , then use that value to pass it to my factory which goint to pull data from rest api link , but the value im sending return nothing without errors, here is my code
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.min.js"></script>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, idService) {
$scope.getSo = function (id){
$scope.myIDs = idService.getID(id);
};
});
app.factory('idService', function($http,$q) {
var oGetID = {};
oGetID.getID = function(id) {
var deferred = $q.defer();
$http.get('http://citysdk.dmci.hva.nl/CitySDK/pois/'+id).then(function(response){
deferred.resolve(response.data);
});
return deferred.promise;
};
return oGetID;
});
</script>
</head>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
send variable
{{myIDs.location.address.value}}
</div>
</body>
</html>
this is the console result of the response
Asynchronous call doesn't work the way you are expecting here. Then happens asynchronously and they return return the data based on API server call. You should expect value after a ajax succeed, by putting .then over it. As internally $http method's return promise.
idService.getID(id).then(function(response){
alert(response);
$scope.myIDs = response;
})

Function in AngularJS doesn't return value back to caller

I am learning AngularJS and creating a small playground for fun. Following code is what I have but I have no idea why the return value from getMessage() doesn't go back to caller. Following is the code
msg.html
<html ng-app="CodeApp">
<head>
<!-- Libs JS -->
<script src="asset/lib/jquery/jquery.min.js"></script>
<script src="asset/lib/angular/angular.min.js"></script>
<script src="asset/lib/angular/angular-sanitize.min.js"></script>
<script src="asset/lib/ui-route/angular-ui-router.min.js"></script>
<script src="asset/lib/angular-base64/angular-base64.min.js"></script>
<script src="asset/lib/bootstrap/js/bootstrap.min.js"></script>
<script src="js/msg-mol.js"></script>
<script src="js/msg-service.js"></script>
<script src="js/msg-controller.js"></script>
<body ng-controller="MsgController">
Msg: {{message}}
</body>
</html>
msg-mol.js
var app = angular.module('CodeApp', []);
msg-controller.js
app.controller('MsgController', ['$scope', 'MsgService', function($scope, MsgService) {
var msg = MsgService.getMessage();
//debugger; (2)
$scope.message = msg;
}]);
msg-service.js
app.factory('MsgService', [ '$http', function($http) {
return {
getMessage : function(){
$http.get('/api/codes').success(function(data) {
var str = "total is " + data.total;
//debugger; (1)
return str;
});
}
};
}]);
1) The output on browser is just "msg:" and {{message}} is empty. I am monitoring the backend and it is pretty sure /api/codes/ have been called to backend and str will be "Total is 35" in debugger mode.
2) when I run the debug mode in chrome, I realized debugger (2) statement has been called before debugger (1). I have no clue about this as getMessage() should be called before debugger(1) stmt.
You have to return promise.
Like this
getMessage: function() {
return $http.get('/api/codes').success(function(data) {
var str = "total is " + data.total;
//debugger; (1)
return str;
});
}
And also have to handle callback using then
MsgService.getMessage().then(function(msg){
$scope.message = msg;
});
You're missing a return from the getMessage function. Change it to i.e.:
app.factory('MsgService', [ '$http', function($http) {
return {
getMessage : function(){
return $http.get('/api/codes').success(function(data) {
var str = "total is " + data.total;
return str;
});
}
};
}]);
Then inside your controller you need to observe the result:
app.controller('MsgController', ['$scope', 'MsgService', function($scope, MsgService) {
MsgService.getMessage().then(function($scope){
$scope.message = msg;
});
}]);
The $http.get returns a Promise that will be resolved when the request to server ends. Since it's asynchronous you need to attach a callback to it in order to process the results.
Better to return a promise and resolve the promise on your controller.
In your service,
getMessage: function () {
return $http.get('/api/codes');
}
In your controller:
getMessage.success(function (data) {
$scope.message = data.total;
})
Look at this example with code..
check it Example you can show firstly first debugger call and after another .. I know i do not give example with service you can understand.
var app = angular.module('CodeApp', []);
app.controller('MsgController', ['$scope','MsgService', function($scope, MsgService) {
var msg = MsgService.getMessage();
alert(2);
debugger;// (2)
$scope.message = msg;
}]);
app.factory('MsgService', [ '$http', function($http) {
return {
getMessage : function(){
var str = "total is";
alert(1);
debugger; //(1)
return str;
}
};
}]);
<html ng-app="CodeApp">
<head>
<!-- Libs JS -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<script src="asset/lib/angular/angular-sanitize.min.js"></script>
<script src="asset/lib/ui-route/angular-ui-router.min.js"></script>
<script src="asset/lib/angular-base64/angular-base64.min.js"></script>
<script src="asset/lib/bootstrap/js/bootstrap.min.js"></script>
<body ng-controller="MsgController">
Msg: {{message}}
</body>
</html>

Fetching JSONP with Angular.js

<html ng-app="movieApp">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
<script>
var base = 'http://api.themoviedb.org/3';
var service = '/movie/862';
var apiKey = '####';
var callback = 'JSON_CALLBACK';
var url = base + service + '?api_key=' + apiKey + '&callback=' + callback;
var movieApp = angular.module('movieApp', []);
movieApp.controller('MovieCtrl', function ($scope, $http){
$http.jsonp(url).then(function(data) {
$scope.movies = data;
});
});
</script>
</head>
<body style="padding:12px;" ng-controller="MovieCtrl">
<div ng-repeat="movie in movies">
<h1>{{movie.title}} {{movie.id}}</h1>
<p>{{movie.overview}}</p>
<img ng-src="http://image.tmdb.org/t/p/w500{{movie.poster_path}}" style='width:200px'/>
</div>
</body>
</html>
Trying to fetch JSON with Angular.js. The information is coming across fine but statuses I believe is also coming across. Resulting in 5 images being placed on the screen, 4 broken and 1 good image along with the data. How can I avoid sending this extra data?
Requesting JSON data with AJAX
You wish to fetch JSON data via AJAX request and render it.
Implement a controller using the $http service to fetch the data and store it in the scope.
<body ng-app="MyApp">
<div ng-controller="PostsCtrl">
<ul ng-repeat="post in posts">
<li>{{post.title}}</li>
</ul>
</div>
</body>
var app = angular.module("MyApp", []);
app.controller("PostsCtrl", function($scope, $http) {
$http.get('data/posts.json').
success(function(data, status, headers, config) {
$scope.posts = data;
}).
error(function(data, status, headers, config) {
// log error
});
});
http://fdietz.github.io/recipes-with-angular-js/consuming-external-services/requesting-json-data-with-ajax.html

Angular js does not get json response from node js

I am trying to establish REST connection between node (middleware) and angular (UI). However, the json is displayed on the browser rather than being routed via the angular controller/html
Node/Express router.js
router.get('/members', function(request, response){
response.header("Access-Control-Allow-Origin", "*");
response.header("Access-Control-Allow-Methods", "GET, POST");
response.setHeader('Content-Type', 'application/json');
var dbdata = [];
var str;
db.get('_design/views555/_view/app_walltime', function (err, body) {
if (!err) {
body.rows.forEach(function(doc) {
dbdata.push({name: doc.key, walltime:doc.value});
});
console.log(dbdata);
response.json(dbdata);
Angular controllers.js
'use strict';
var phonecatApp = angular.module('phonecatApp', []);
phonecatApp.config(['$httpProvider', function($httpProvider, $routeProvider, $locationProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}
]);
phonecatApp.controller('PhoneListCtrl', function ($scope, $http, $templateCache) {
alert('asdsad');
$scope.list = function() {
alert('hereh');
var url = 'http://192.168.59.103:8072/members';// URL where the Node.js server is running
$http.get(url).success(function(data) {
alert(data);
$scope.phones = data;
});
};
$scope.list();
});
html - testangular.js
<html ng-app="phonecatApp">
<head>
<meta charset="utf-8">
<title>My HTML File</title>
<link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.css">
<script src="/bower_components/angular/angular.js"></script>
<script src="/bower_components/angular-route/angular-route.min.js"></script>
<script src="js/controllers.js"></script>
</head>
<body ng-controller="PhoneListCtrl">
<div class="container-fluid">
<div class="row">
<div class="col-md-2">
<ul class="phones">
<li ng-repeat="phone in phones | filter:query">
{{phone.name}}
<!--<p>{{phone.walltime}}</p> -->
</li>
</ul>
</div>
</div></div>
What is see is the following on the browser
[{"name":"app1","walltime":"1050"},{"name":"app2","walltime":"30"}]
I seem to be missing some configuration to let node and angular communicate. Please let me know what I am doing wrong.
What you see on the browser's window is a JSON object, that is the result of your request.
With the line $scope.phones = data;, you're simply assigning to $scope of Angular the data object, without actually parsing it.
The result is that Angular is not able to understand in the ng-repeat directive what actually {{phone.name}} and {{phone.walltime}} are and the JSON string is shown.
In order to have the ng-repeat directive working as expected, you have to parse first the JSON object, process it (creating for example a custom object and assigning its properties) and then assign it to $scope object.
You could perform the parse using something like
JSON.parse(data);.
Please have a look at this question for further information.
Or even using the Angular's builtin function angular.fromJson(data).
An example could this:
$http.get(url).success(function(data) {
alert(data);
$scope.phones = angular.fromJson(data);
});
};
Test this :
var url = 'http://192.168.59.103/members';
$http.get(url).then(
function(response) {
console.log('success',response)
},
function(data) {
// Handle error here
})

Categories

Resources