I have my page with element like this
<div ng-app="myApp" class="ng-cloak" ng-controller="MyController as ctrl">
<div class="item" ng-repeat="i in ctrl.items">
<h3>Some text...</h3>
<p ng-bind="i.id"></p>
<button ng-click="alertValue(i.id)">DETAILS</button></p>
</div>
</div>
My controller looks like this and has a method
'use strict';
App.controller('MyController', ['$scope', 'Item', function ($scope, Item) {
$scope.alertValue = function (id) {
alert('clicked:' + id);
}
}
Which works fine, I get the alert with the id. But how do I send this id from controller to my service? I tried following few tutorials, but they are all different and I got completly lost in it. Can anyone explain this to me in a simple way and show how to do this?
May be I need to provide some additional info? Thanks.
I try not to use scope so I would create a function for that click on my controller. Then it's just a matter of doing what you want with it.
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script>
angular.module('my-app', [])
.service('Items', function() {
return {
doWork: function(id) {
console.log(id);
}
};
})
.controller('ItemsCtrl', function(Items) {
var vm = this;
vm.items = [
{ id: 1, name: 'Foo' },
{ id: 2, name: 'Bar' },
{ id: 3, name: 'Baz' },
];
vm.doWork = function(id) {
Items.doWork(id);
};
});
</script>
<div ng-app="my-app">
<div ng-controller="ItemsCtrl as ctrl">
<ul>
<li ng-repeat="item in ctrl.items">
{{item.name}}
<button ng-click="ctrl.doWork(item.id)">Do Work</button>
</li>
</ul>
</div>
</div>
You have to use $http service. $http service facilitates communication with the remote HTTP servers.
$http service use then method in order to attach a callback.
The then() method takes two arguments: a success and an error callback which will be called with a response object.
Using the then() method, attach a callback function to the returned promise.
Something like this:
app.controller('MainCtrl', function ($scope, $http){
$http({
method: 'GET',
url: 'api/url-api'
}).then(function (success){
},function (error){
});
}
See reference here
Shortcut methods are also available.
$http.get('api/url-api').then(successCallback, errorCallback);
function successCallback(response){
//success code
}
function errorCallback(error){
//error code
}
You have to inject the service inside controller to pass some data to it.
app.controller.js
App.controller('MyController', ['$scope', 'ItemService', function ($scope, ItemService) {
$scope.alertValue = function (id) {
ItemService.id = id;
}
}
Please refer this for more information on creating and registering a service in angular.
Related
I'm trying to get data from a Web API and display it in a table, but it doesn't work.
I am new to angularjs and i code simple program to get data from the Web API and display in table.but i am not able to get data.
Module
var app = angular.module("myApp", []);
Service
app.service("myService", function ($http) {
//get All Eployee
this.getEmployees = function () {
return $http.get('http://apidemo.gouptechnologies.com/api/admin');
};
})
Controller
app.controller("myCntrl", function ($scope, myService) {
$scope.divEmployee = false;
GetAllEmployee();
function GetAllEmployee() {
alert('home');
var getData = myService.getEmployees();
getData.then(function (emp) {
$scope.employees = emp.data;
}, function () {
alert('Error in getting records');
});
}
});
The JS code is included in the head tag of the HTML file.
HTML body
<body>
<div ng-app="myApp" ng-controller="myCntrl">
<ul>
<li ng-repeat="x in employees">
{{ x.username + ', ' + x.password }}
</li>
</ul>
</div>
</body>
The API URL is legitimate.
Thanks.
Let example a json file in "data/branchList.json" directory, And i am trying to access all data from json file using $http.
It may help you to call a rest service aslo. check this example
data/branchList.json
[
{
"branch_id": 1,
"branch_name": "Mummbai",
"branch_address": "India"
},
{
"branch_id": 2,
"branch_name": "New York",
"branch_address": "US"
}
]
Controller
angular.module('myApp')
.controller('myCntrl', ['$http', '$state', function ($http, $state) {
'use strict';
var vm = this;
function init(){
vm.branchs = '';
loadBranch();
}
init();
function loadBranch(){
$http.get('data/branchList.json').success(function(response){
vm.branchs = response;
})
}
}]);
In this example i am storing all the data in vm.branches variable, you can use this variable in html page
HTML
<li class="col-sm-6" ng-repeat = "branch in vm.branchs">
<strong>{{branch.branch_name}}</strong>
<span>{{branch.branch_address}}</span>
</li>
im working with AnuglarJS 1.4.8. I want give out the data with ng-repeat.
I have the following problem and i have no more ideas to solve it. I tried the solutions from AnuglarJS but i doesnt work.
Could someone help me please.
Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: []
http://errors.angularjs.org/1.4.8/$rootScope/infdig?p0=10&p1=%5B%5D
Service:
.service('database', function ($http) {
self = this;
this.url = 'http://localhost:3001';
this.getPersons = function(cb){
return $http({
method: 'GET',
url: self.url + '/loadperson'
}).success(function (data) {
cb(data);
});
};
});
Controller:
angular.module('myApp')
.controller('personCtrl', function ($scope, database) {
$scope.people = function(){
return{
getAll: function () {
database.getPersons(function (data) {
return data;
// should return a Object(id, name)
});
}
}
};
HTML:
<div ng-repeat="people in people().getAll()">
<p>{{people.name}}</p>
</div>
You are missing the non-blocking way of javascript. Try following, it should work
Controller:
angular.module('myApp')
.controller('personCtrl', function ($scope, database) {
$scope.loadPeoples = function(){
return{
getAll: function () {
database.getPersons(function (data) {
$scope.peoples = data;
// should return a Object(id, name)
});
}
}
};
$scope.loadPeoples();
})
HTML:
<div ng-repeat="people in peoples">
<p>{{people.name}}</p>
</div>
Try that.
Service:
.service('database', function ($http) {
self = this;
this.url = 'http://localhost:3001';
this.getPersons = function(){
return $http({
method: 'GET',
url: self.url + '/loadperson'
});
};
});
Controller:
angular.module('myApp')
.controller('personCtrl', function ($scope, database) {
database.getPerson().success(function(data) {
$scope.people = data;
});
});
HTML:
<div ng-repeat="person in people">
<p>{{person.name}}</p>
</div>
You should also be aware that you shouldn't return each time a NEW array for iterating. Otherwise angular will keep calling that function for retrieving a "stable" value for the array.
You've made a common error in javascript when running asynchronous queries. The pattern goes:
function outerFunction() {
invokeInnerFunction(function() {
return 3;
}
}
What does outerFunction() return? An error is to think it returns 3, but the answer is actually that outerFunction doesn't return anything.
Likewise, in your example getAll isn't actually returning anything; it's just calling an asynchronous method. This asynchronous method invoked $http, which triggers a digest loop which will result in getAll being called again, and so on for ever. Be thankful that angular can detect this problem.
You only want to call the database query once on startup, and initialize the list of people. Simply store this list in a variable so it won't query the database again on the next digest loop.
angular.module('myApp')
.controller('personCtrl', function ($scope, database) {
$scope.allPeople = [];
database.getPersons(function(data) {
$scope.allPeople = data;
});
};
An then for your HTML
<div ng-repeat="people in allPeople">
<p>{{people.name}}</p>
</div>
Much simpler.
Have you tried making a separate function to fetch the entities from the data base, then put this data in a variable, that you then will pass to the ngRepeat ?
your controller
angular.module('myApp')
.controller('personCtrl', function ($scope, database) {
$scope.people = [];
$scope.getPeople = function(){
return{
getAll: function () {
database.getPersons(function (data) {
$scope.people = data;
return;
// should return a Object(id, name)
});
}
}
//load the list of people
$scope.getPeople();
};
your view
<div ng-repeat="person in people">
<p>{{person.name}}</p>
</div>
I am making my first project using Angularjs 1.4.3.
In my controller I am making a http request, in the success method of this http request I am updating a scope variable. In http call I am getting the latest values but in the view side its not updating the values.
Plunker Link (#rupesh_padhye thanks). (Since it is calling the servlet action, so no data will be shown in Plunker)
app.controller('measuresCtrl', ['$scope', '$modal', '$http', function($scope, $modal, $http) {
$scope.groups = []
$scope.loadAllMeasure = function() {
$http.get("fetchAllMeasure")
.success(function(data) {
console.log("Before insert");
console.log($scope.groups);
$scope.groups = data.measures;
console.log("After insert");
console.log($scope.groups);
})
.error(function() {
});
};
$scope.loadAllMeasure();
$scope.submit = function (form) {
$http({
method: 'POST',
url: 'saveMeasure',
data: {
id: form.id,
name: form.name,
description: form.description
},
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).success(function(data, status, headers, config) {
$scope.loadAllMeasure();
}).error(function(data, status, headers, config) {
});
}
})
And whenever I am performing any CRUD operation on measures I am calling a method $scope.loadAllMeasure();. But its not updating the values in the view (jsp) page.
I have tried $scope.$apply method but I am getting Error: $digest already in progress.
When I printed the value for $scope.groups using console.log inside success method, then its showing the latest values.
In my view (jsp) page I am just using ng-repeat function to show all the records in table format.
Code for my view page (minimal code) -
<div ng-repeat="group in groups | orderBy:'name'">
<div>
<input type="checkbox" id="checkbox-{{group.id}}" class="ui-checkbox" /><label for="checkbox-{{group.id}}">{{group.name}}</label>
</div>
<div>{{ group.description}}</div>
<div>
<div class="fa fa-pencil button" data="{{group.id}}" id="{{::elementId}}" ng-click="showEditForm(group.id, $event)"></div>
<div class="fa fa-trash button" data="{{group.id}}" ng-click="deleteGroup(group.id)"></div>
<div class="fa fa-clone button" data="{{group.id}}" id="{{::elementId}}" ng-click="showCloneForm(group.id, $event)"></div>
</div>
</div>
Values in console.log are
Before insert
Object { id=1, description="Measure Description1", name="Demo"}]
And
After Insert
[Object { id=1, description="Measure Description1", name="Demo"}, Object { id=2, description="Description2", name="Demo2"}]
How to update scope variable value in view after http call?
After assigning the new data to a $scope variable call:
$scope.$digest();
This will update the current scopes values
reference here: https://docs.angularjs.org/api/ng/type/$rootScope.Scope
I cant see anything wrong with your example code.
I have created a JSFiddle to try and help you.
The server call has been replaced by a setTimeout function that returns a promise.
Please see JSFiddle https://jsfiddle.net/sjwkbzxa/
Please see example below:
<div data-ng-controller="TestController as vm">
<button data-ng-click="loadAllMeasure()">Load List from Server</button>
<ul>
<li data-ng-repeat="group in groups | orderBy:'name'">
<span>{{group.description}}</span>
</li>
</ul>
</div>
The javascript:
angular.module('application',[]).controller("TestController", ['$scope', '$q', function($scope, $q){
$scope.groups = [{ id:1, description:"Initial List", name:"Demo"}];
$scope.loadAllMeasure = function(){
loadData().then(function(data){
$scope.groups = data;
});
};
function loadData(){
var deferred = $q.defer();
setTimeout(function(){
var data = [{ id:1, description:"Measure Description1", name:"Demo"}, { id:2, description:"Description2", name:"Demo2"}];
deferred.resolve(data);
}, 3000);
return deferred.promise;
}
}]);
Maybe you are missing something on your side that we cant see?
I'm a little late to answer this, but here are my 2 cents:
A simple assignment of the server data (response.data) to a $scope object didnt seem to work for me
$scope.something = response.data //didn't work
So, I returned a promise object from the service into the controller and then use
angular.copy(response.data,$scope.something)
to copy the values returned from the server. You could also pass the $scope.something to the service as a parameter to the function and have angular.copy in the service function as well, but i don't know if it's a good practise to do that.
$scope.loadAllMeasure = function() {
CalltoServer();
};
CalltoServer = function() {
return $http.get("fetchAllMeasure")
.success(function(data) {
$scope.groups = data.measures;
})
.error(function() {
});
}
try this , the success will be after 2 or 3 seconds so i guess inside the event it takes rist to bind
Hey I also faced the same issue and if anyone is still looking, it is caused by change in the $scope variable inside the $http. I think a new $scope is being created inside the success function(some prototypical inheritance stuff).
So make a copy of the variable $scope, something like
var s = $scope;
and then change
s.groups = someData;
Your code:
app.controller('measuresCtrl', ['$scope', '$modal', '$http', function($scope, $modal, $http) {
var s = $scope;
$scope.groups = []
$scope.loadAllMeasure = function() {
$http.get("fetchAllMeasure")
.success(function(data) {
console.log("Before insert");
console.log($scope.groups);
s.groups = data.measures;
console.log("After insert");
console.log($scope.groups);
})
.error(function() {
});
};
$scope.loadAllMeasure();
$scope.submit = function (form) {
$http({
method: 'POST',
url: 'saveMeasure',
data: {
id: form.id,
name: form.name,
description: form.description
},
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).success(function(data, status, headers, config) {
$scope.loadAllMeasure();
}).error(function(data, status, headers, config) {
});
}
})
Overview
I am building an app (running on MAMP) that holds contact information that will expand to hold more data such as project name & deadline, once this part is functional.
Questions
When the user visits /projects.php#/project/ I would like them to see a list of all the project names with a link to their detail page.
How should I write the following to access all of my data?
Do I need the .json at the end?
What does the #id do?
return $resource('data/project.json/:id', {id: '#id'});
When the user visits /projects.php#/project/a-gran-goodn I would like them to see the details about this project(for now, just the name & address).
How should I write the following to return my data by Id?
$scope.project = $routeParams.id ? Project.get({id: $routeParams.id}): new Project();
plunkr file
http://plnkr.co/edit/7YPBog
project.json
This file lives on http://localhost:8888/angularjs/ProjectsManager/data/project.json
[
{ "address" : [ " 3156 Dusty Highway",
" Teaneck New Jersey 07009-6370 US"
],
"id" : "a-gran-goodn",
"name" : "Grania Goodner",
"phone" : " (862) 531-9163"
},
{ "address" : [ " 62 Red Fawn Moor",
" Rodney Village West Virginia 25911-8091 US"
],
"id" : "b-aime-defranc",
"name" : "Aimery Defranco",
"phone" : " (681) 324-9946"
}
]
app.js
var projectsApp = angular.module('projects', ['ngResource']);
projectsApp.config(function($routeProvider) {
$routeProvider
.when('/', {
controller: 'ProjectListCtrl',
templateUrl: 'partials/projectlist.html'})
.when('project/:id', {
controller: 'ProjectDetailCtrl',
templateUrl: 'partials/projectdetail.html'
})
.otherwise('/');
});
projectsApp.factory('Project', function($resource) {
return $resource('data/project.json/:id', {id: '#id'});
});
projectsApp.controller('ProjectListCtrl', function(Project, $scope) {
$scope.projects = Project.query();
console.log($scope.projects);
});
projectsApp.controller('ProjectDetailCtrl', function(Project, $routeParams, $scope) {
$scope.project = $routeParams.id
? Project.get({id: $routeParams.id})
: new Project();
});
partials/projectlist.html
Add new item
<ul class="unstyled">
<li ng-repeat="project in projects">
<div class="well">
<h2><small>{{project.id}}</small> {{project.name}}</h2>
View Info for {{project.name}}
</div>
</li>
</ul>
partials/projectdetails.html
<h3>Information</h3>
<p>Name: {{project.name}}</p>
<p>Phone Number: {{project.phone}}</p>
<p ng-repeat="line in project.address">{{line}}</p>
index.php
<?php
header('Access-Control-Allow-Origin: *');
?>
<!doctype html>
<html ng-app="projects">
<head>
<meta charset="utf-8">
<title ng-bind="title" ng-cloak>Restaurant —</title>
<link href="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.no-icons.min.css" rel="stylesheet">
</head>
<body ng-controller="ProjectListCtrl">
<a class="brand" href="#">Projects Manager</a>
<div id="app-container" class="container-fluid">
<div class="row-fluid">
<div class="span12" id="main" ng-view>
</div><!--/.span12-->
</div><!--/.row-fluid-->
<footer>Copyright Projects © 2013</footer>
</div><!--/.container-->
<script src="http://code.jquery.com/jquery-1.10.0.min.js"></script>
<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
<!-- Don't forget to load angularjs AND angular-resource.js -->
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular-resource.js></script>
<!--Controllers-->
<script src="app.js"></script>
</body>
</html>
Since you can't query against a raw JSON file like you can with RESTful-style URLs (which is what $resource is built to do), you can instead get a copy of the JSON and then build your own query, get, etc. that looks at the data and returns the right thing. It's a bit tricky because you also want to support new Project, which doesn't really make sense when using a file-backed store, but this example supports it:
projectsApp.factory('Project', function($http) {
// Create an internal promise that resolves to the data inside project.json;
// we'll use this promise in our own API to get the data we need.
var json = $http.get('project.json').then(function(response) {
return response.data;
});
// A basic JavaScript constructor to create new projects;
// passed in data gets copied directly to the object.
// (This is not the best design, but works for this demo.)
var Project = function(data) {
if (data) angular.copy(data, this);
};
// The query function returns an promise that resolves to
// an array of Projects, one for each in the JSON.
Project.query = function() {
return json.then(function(data) {
return data.map(function(project) {
return new Project(project);
});
})
};
// The get function returns a promise that resolves to a
// specific project, found by ID. We find it by looping
// over all of them and checking to see if the IDs match.
Project.get = function(id) {
return json.then(function(data) {
var result = null;
angular.forEach(data, function(project) {
if (project.id == id) result = new Project(project);
});
return result;
})
};
// Finally, the factory itself returns the entire
// Project constructor (which has `query` and `get` attached).
return Project;
});
You can use the results of query and get like any other promise:
projectsApp.controller('ProjectListCtrl', function(Project, $scope) {
$scope.projects = Project.query();
});
projectsApp.controller('ProjectDetailCtrl', function(Project, $routeParams, $scope) {
$scope.project = $routeParams.id
? Project.get($routeParams.id)
: new Project();
});
Note the change to Project.get($routeParams.id); also, the updated Plunker also fixes a problem in your $routeProvider configuration.
This is all demonstrated here: http://plnkr.co/edit/mzQhGg?p=preview
i will paste here a generic code i use to fetch json from your local or a remoteserver maybe it will help you:
it uses a factory that you can call when you need it.
app.factory('jsonFactory', function($http) {
var jsonFactory= {
fromServer: function() {
var url = 'http://example.com/json.json';
var promise = $http.jsonp(url).then(function (response) {
return response.data;
});
return promise;
},
hospitals: function() {
var url = 'jsons/hospitals.js';
var promise = $http.get(url).then(function (response) {
return response.data;
});
return promise;
}
};
return jsonFactory;
});
Then when you need to call it:
function cardinalCtrl(jsonFactory, $scope, $filter, $routeParams) {
jsonFactory.hospitals().then(function(d){
$scope.hospitals=d.hospitals;
});
jsonFactory.fromServer().then(function(d){
$scope.fromServer=d.hospitals;
});
}
Right now we are facing an issue in a controller that calls a DataService (Parse), the problem is that this code does not work:
function MainCtrl($scope, DataService, $location)
{
$scope.actionList = function() {
// Call the service and fetch the list of signatures that match the given action ID
DataService.getActions(function (results) {
$scope.$apply(function () {
// Apply the results to the signatureList model so it will refresh the table in the view
$scope.actionList = results;
});
});
};
}
I put a breakpoint in the DataService line but it doesn't get hit, but if I implement the Ctrl in this way it does get call and It works!!:
function MainCtrl($scope, DataService, $location)
{
// Call the service and fetch the list of signatures that match the given action ID
DataService.getActions(function (results) {
$scope.$apply(function () {
// Apply the results to the signatureList model so it will refresh the table in the view
$scope.actionList = results;
});
});
}
Any idea why is this happening??
Apart from that once is working (with the second implementation) I would like to show a property of the activity, if I try to get the property like this it does not work:
<div id="wrapper"><div id="scroller">
<div ng-controller="MainCtrl">
<ul id="thelist">
<li ng-repeat="action in actionList">{{action.get('Action')}}</li>
</ul>
</div>
</div></div>
But if I try to get the whole object like {{action}} I can actually see all the entries.
Change the controller to
function MainCtrl($scope, DataService, $location) {
$scope.getActionList = function() {
DataService.getActions(function(results) {
$scope.$apply(function() {
$scope.actionList = results;
});
});
};
$scope.getActionList();
}
Then if you want to reload actionList call getActionList()
Any idea why is this happening??
In your first example, you are simply defining a function named actionList on object $scope. Defining a function won't execute it (see #Arun's answer).
To show your data in the view, you can use normal JavaScript dot notation. If an action object looks like this:
{ prop1: 'property 1', prop2: [1, 2], prop3: { name: 'Javito'} }
You could write the view/HTML as follows:
<ul id="thelist">
<li ng-repeat="action in actionList">
prop1: {{action.prop1}}<br>
prop2: {{action.prop2[0]}} {{ action.prop2[1] }}<br> <!-- or use another ng-repeat here -->
prop3.name: {{action.prop3.name}}
</li>
</ul>