How to display resource object in Angular JS - angularjs

I have a problem with displaying records in angular...
query like this..
Angular Controller
angular.module('MyApp')
.controller('CountriesCtrl', function ($scope, $rootScope, $routeParams, Countries) {
Countries.query({}, function (countries) {
//Countries.get() return Expected response to contain an object but got an array so i use countries.query....
$scope.countries = countries;
console.log(countries);
});
})
which returns
.. Using the returned data How can I show in angular with ng-repeat..
thank you

Use ng-repeat over the array:
<div ng-repeat="country in countries">
<span>{{country.name}}</span>
</div>
I suggest anyway to follow some good tutorial and the documentation: this is pretty much basic stuff. Documentation on ng-repeat can be found here

Related

Selecting the proper item in a select list when the form is populated before the list

Let's say I have a form for editing customers with a cities list specified through a select element. The real form has a lot of lists, however, this will do for now.
The form is populated by making a rest api call called /customer/{customerId}.
The list is populated by making a rest api call called /cities.
The calls are made in sequence in the controller using $http.get to get the cities and the other one via a $resource get (not in the code snippet below).
The problem is that in case the call to get the customer data for comes back first, the form selects the first city in the list instead of the right city.
Here are some code snippets:
html:
<select id="Select3" class="form-control" ng-model="formData.CityId">
<option ng-repeat="j in Cities" value="{{j.CityId}}">{{j.City}}</option>
</select>
Controller:
.controller('customerInfoCtrl', ['$scope', '$http', '$modal', '$location', 'CustomerApi', function ($scope, $http, $modal, $location, CustomerApi) {
$http.get('../api/v1/cities').success(function (data) {
$scope.Cities = data;
});
$scope.formData = CustomerApi.get({ id: $scope.customerId }, function () {
...
});
....
How do I fix this? Keep in mind that the form has lots of lists. Is there a pattern that can be applied systematically?
I know about $scope.$apply() or $scope.$apply(fn). Should I call one of these in the success function for the call that gets the cities?
Thanks
An update:
Converting to ng-options seems to do the trick. I have to do more testing.
<select id="Select3" class="form-control" ng-model="formData.CityId" ng-options="j.CityId as j.City for j in Cities">
</select>
Another update:
I created a plnkr where you can see the issue: http://plnkr.co/edit/Se8OIuxYBv4QXeH3Jgqh?p=preview
if you want to make sure that some data loads before other, use the callback function you get when using both of your get() methods.
So if you wanted to load cities first, it could be something like that:
$http.get(../api/v1/cities').success(function (data) {
$scope.Cities = data;
//now that the cities are loaded, you can loead something else here.
$scope.formData = CustomerApi.get({ id: $scope.customerId }, function () {
//this will always be loaded after cities
});
$scope.loadSmthElse....
}

AngularJS Communication between ng-repeat and controller

I've just started using AngularJS, and as a project I decided to build a simple app for managing bookmarks. I want to be able to maintain a list of bookmarks and add/remove items. I'm using Django with Django REST framework, and Angular.
So far I've written a service to grab the bookmarks from the database, and I can print them to the console from my controller, but ng-repeat doesn't seem to be seeing them.
Here's my code for the service:
.factory('BookmarkService', ["$http", function ($http) {
var api_url = "/api/bookmarks/";
return {
list: function () {
return $http.get(api_url).then(function (response) {
return response.data
})
}
}
}]);
And for the controller:
.controller("ListController",
["$scope", "BookmarkService", function ($scope, BookmarkService) {
$scope.bookmarks = BookmarkService.list();
console.log($scope.bookmarks);
}]);
And here's the HTML:
<div ng-controller="ListController as listCtrl">
<md-card>
<md-card-content>
<h2>Bookmarks</h2>
<md-list>
<md-list-item ng-repeat="bookmark in listCtrl.bookmarks">
<md-item-content>
<div class="md-tile-content">
<p>{[{ bookmark.name }]} - {[{ bookmark.url }]}</p> // used interpolateProvider to allow "{[{" instead of "{{"
</div>
<md-divider ng-if="!$last"></md-divider>
</md-item-content>
</md-list-item>
</md-list>
</md-card-content>
</md-card>
</div>
When I print to the console from the controller I can see a promise object but ng-repeat isn't repeating:
image of promise object
I'd really appreciate if someone could help me to find my mistake and to understand why it is happening. I'm still not entirely comfortable with how all these parts fit together.
Thanks for your time!
There's two problems that I see with the code in question.
The first is that using the controller as syntax (ng-controller="ListController as listCtrl") requires properties to be bound to the controller instance and not to the scope if you address them using the controller name. In your case,
.controller("ListController",
["BookmarkService", function (BookmarkService) {
this.bookmarks = BookmarkService.list();
console.log(this.bookmarks);
}]);
The second is that you are assigning a promise to your $scope.bookmarks property. The repeater is expecting an array of objects to iterate over. You really want to assign the value resolved by the promise to $scope.bookmarks.
Instead of this
$scope.bookmarks = BookmarkService.list();
Do this
BookmarkService.list().then(function(result){
this.bookmarks = result;
});
The final version of your controller should look something like this
.controller("ListController",
["BookmarkService", function (BookmarkService) {
this.bookmarks = BookmarkService.list();
console.log(this.bookmarks);
}]);
This is simple. Ng-repeat is not working with promises. So, you can go with two ways:
BookmarkService.list().then(function(responce){
$scope.bookmarks = responce.data;
});
Another way is to create own repiter ^)
Ng-repeat doc

angularjs value vs factory

I am new to angularjs. I am trying to find out when to use value vs factory as a service. Here is my simple code from egghead.io tutorial:
.value('Data', function(){
return {message:"I am data from a service"};
})
The Data.message is bound to an input field. When I start the page, there is nothing in the input fields. If I change value to factory, the default message appears in the input field.
Here is the contoller:
controller('FirstCtrl', ['$scope','Data',function($scope, Data) {
$scope.data = Data;
console.log('exiting first controller');
}])
and the index file:
<div ng-controller="FirstCtrl">
<input type="text" ng-model="data.message">
<h1>{{data.message}}</h1>
</div>
Why is the page blank when using value? My assumption is that value is not calculated or computed when the app starts whereas factory is?
Also, where can I find some documentation on $provide? Thank you all.
Set the value to an object, rather than a function:
app.value('Data', {message:"I am data from a service"});
Plunker
See also provide.value(), and this video about $provide (value, constant, service, factory, decorator, provider)
You should declare the controller as
app.controller('DataController', ['Data', function DataController(Data){
this.data = Data;
}]);
and then use it in your page like in my code
<div ng-controller='DataController as dataController'>
{{dataController.data()}}
</div>

AngularJS - Using a Service as a Model, ng-repeat not updating

I'm creating an ajax search page which will consist of a search input box, series of filter drop-downs and then a UL where the results are displayed.
As the filters part of the search will be in a separate place on the page, I thought it would be a good idea to create a Service which deals with coordinating the inputs and the ajax requests to a search server-side. This can then be called by a couple of separate Controllers (one for searchbox and results, and one for filters).
The main thing I'm struggling with is getting results to refresh when the ajax is called. If I put the ajax directly in the SearchCtrl Controller, it works fine, but when I move the ajax out to a Service it stops updating the results when the find method on the Service is called.
I'm sure it's something simple I've missed, but I can't seem to see it.
Markup:
<div ng-app="jobs">
<div data-ng-controller="SearchCtrl">
<div class="search">
<h2>Search</h2>
<div class="box"><input type="text" id="search" maxlength="75" data-ng-model="search_term" data-ng-change="doSearch()" placeholder="Type to start your search..." /></div>
</div>
<div class="search-summary">
<p><span class="field">You searched for:</span> {{ search_term }}</p>
</div>
<div class="results">
<ul>
<li data-ng-repeat="item in searchService.results">
<h3>{{ item.title }}</h3>
</li>
</ul>
</div>
</div>
</div>
AngularJS:
var app = angular.module('jobs', []);
app.factory('searchService', function($http) {
var results = [];
function find(term) {
$http.get('/json/search').success(function(data) {
results = data.results;
});
}
//public API
return {
results: results,
find: find
};
});
app.controller("SearchCtrl", ['$scope', '$http', 'searchService', function($scope, $http, searchService) {
$scope.search_term = '';
$scope.searchService = searchService;
$scope.doSearch = function(){
$scope.searchService.find($scope.search_term);
};
$scope.searchService.find();
}]);
Here is a rough JSFiddle, I've commented out the ajax and I'm just updating the results variable manually as an example. For brevity I've not included the filter drop-downs.
http://jsfiddle.net/XTQSu/1/
I'm very new to AngularJS, so if I'm going about it in totally the wrong way, please tell me so :)
In your HTML, you need to reference a property defined on your controller's $scope. One way to do that is to bind $scope.searchService.results to searchService.results once in your controller:
$scope.searchService.results = searchService.results;
Now this line will work:
<li data-ng-repeat="item in searchService.results">
In your service, use angular.copy() rather than assigning a new array reference to results, otherwise your controller's $scope will lose its data-binding:
var new_results = [{ 'title': 'title 3' },
{ 'title': 'title 4' }];
angular.copy(new_results, results);
Fiddle. In the fiddle, I commented out the initial call to find(), so you can see an update happen when you type something into the search box.
The problem is that you're never updating your results within your scope. There are many approaches to do this, but based on your current code, you could first modify your find function to return the results:
function find(term) {
$http.get('/json/search').success(function(data) {
var results = data.results;
});
//also notice that you're not using the variable 'term'
//to perform a query in your webservice
return results;
}
You're using a module pattern in your 'public API' so your searchService returns the find function and an array of results, but you'd want to make the function find to be the responsible for actually returning the results.
Setting that aside, whenever you call doSearch() in your scope, you'd want to update the current results for those returned by your searchService
$scope.doSearch = function(){
$scope.searchService.results = searchService.find($scope.search_term);
};
I updated your jsfiddle with my ideas, is not functional but i added some commments and logs to help you debug this issue. http://jsfiddle.net/XTQSu/3/

Angularjs - Using controller

I am new to Angular.js. I currently have the following html code, where I define my div with my file html ( ng-include ) and my controller ( ng-controller ):
<div id="customerinformation-maxi" ng-include="'pages/customerinformation-maxi.html'" ng-controller="customerInformationMaxiController" class="col-md-12"></div>
This is the html code for the called html in directive ng-include ( customer-information.html ):
<div class="row">
<div class="col-md-2">
<span>Customer Number</span>
<span>{{customer.number}}</span>
</div>
<div class="col-md-2">
<span>Portfolio</span>
<span>{{custom.portfolio}}</span>
</div>
</div>
This is the js controller:
angularRoutingApp.controller('customerInformationMaxiController', function($scope, $http) {
//Here i need to load the model variable with a literal text {{customer.number}} and {{customer.portfolio}}, how could do it? using scope object? with a json file?
});
Here I need to load the model variable with a literal text {{customer.number}} and {{customer.portfolio}}.
How could do it? Using scope object? With a json file?
Thanks for any help.
Yes, you should do it using the $scope object.
To get a general overview, here is a hello-world example:
<div ng-controller="HelloController">
{{ helloMessage }}
</div>
And in you controller's code (js file or script tag into the html):
var myApp = angular.module('myApp',[]);
myApp.controller('HelloController', ['$scope', function($scope) {
$scope.helloMessage= 'Hello World!';
}]);
But I foresee some nesting in the provided snippet of your question, so you 're probably dealing with a collection of objects which means that you have to iterate through it, in the html part, using the ng-repeat directive, like:
<tr ng-repeat="customer in customers>
<td>{{customer.number}}</td>
<td>{{customer.portfolio}}</td>
</tr>
So, your controller's functionality should contain the customers object, like:
angularRoutingApp.controller('customerInformationMaxiController', function($scope, $http) {
var customers=[
{
number:'123',
portfolio: 'blah blah'
},
{
number:'124',
portfolio: 'blah blah'
},
{
number:'125',
portfolio: 'blah blah'
}
];
});
For further reference, you could read two respective example I have written:
Angular.js Controller Example
Angular.js JSON Fetching Example
The second one is only to see a sample usage of traversing collections, it is not meant that you have to use json, as you stated in your question; but I see that you also defined the $http service in your controller, so if it's about data that are going to be fetched from a remote destination, the JSON Fetching Example should probably help you better).
You should use scope objects to give values to your modal variables.
angularRoutingApp.controller('customerInformationMaxiController', function($scope, $http) {
$scope.customer.number = 'sample number';
$scope.customer.portfolio = 'sample portfolio';
});

Resources