Unable to set selected value in AngularJS - angularjs

i have several select boxes on my edit form, now when the page loads data is loaded into it, this works for all textboxes and checkboxes but not selectboxes, i am unable to set the selected value for them i have googled so many things but i still cannot seem to find what i am doing wrong, this is my html:
<div class="form-group" ng-init="getRoles()">
<label for="roles">Role</label>
<select style="width: 100%;" data-toggle="select2" ng-model="form.role_id" ng-options="item.id as item.role for item in roles">
</select>
</div>
This is the function that gets and sets the user info in my controller:
$scope.getUserInfo = function() {
UserService.get($stateParams.id)
.success(function (data, status, headers, config) {
if (data.user != undefined)
{
$scope.form = data.user;
}
})
};
This the function that gets and sets the roles in my controller:
$scope.getRoles = function() {
RoleService.get()
.success(function (data, status, headers, config) {
if (data.roles != undefined)
{
$scope.roles = data.roles;
}
})
};
I have verified the returned data and it is indeed correct.
This is the returned JSON:
{"user":{"id":2,"email":"xxxxxxx#gmail.com","role_id":2,"institution_id":null,"is_active":1}}
And this is the returned roles JSON:
{"roles":[{"id":2,"role":"System"},{"id":3,"role":"Administrator"},{"id":4,"role":"Instructor"}]}

You need to write
ng-model="user.role_id"

Related

Display Angular Loading Bar in a specific $http request NOT in the whole module

When I used the chieffancypants loadingBar, the loading bar appears from the start of the loading of the page and to every $http request that i make,
I want to display only the loading bar progress when I click the search button which retrieves a large amount of data.
var mtg = angular.module('mtgApp',['ui.bootstrap','chieffancypants.loadingBar','ngAnimate']);
mtg.controller('mtgController',function($scope,$http,$location)
{
var apiBaseUrl = "http://sampleAPIURL.com";
$scope.token = "sampletoken";
$scope.processForm = function()
{
$http({
method: 'POST',
url: apiBaseUrl + 'flight/search?token=' + $scope.token,
data: {
//my json request
//flightForm.from,
//flightForm.to,
//flightForm.date
}
}).success(function(data, status, headers, config){
$scope.displayResults(data.searchId);
}).error(function(data, status, headers, config){
console.log("Check For Errors");
});
}
$scope.displayResults = function(searchId)
{
$http.get(apiBaseUrl + 'Flight/results/'+searchId+'?$top=50&token=' + $scope.token).success(function(data)
{
$scope.results = data.flightResult;
$location.path('/search/results');
});
};
});
In my search
<form ng-controller = "mtgController">
<input type = "text" ng-model = "flightForm.from">
<!--uses $http request to get the suggested location-->
<input type = "text" ng-model = "flightForm.to">
<!--uses $http request to get the suggested location-->
<input type = "text" ng-model = "flightForm.date">
<input type = "button" ng-click = "processForm()" value = "Search">
</form>
In my html search/results
<form>
<div ng-controller = "mtgController">
<div ng-repeat = "result in results">
//{{result.details}} and so on and so on
</div>
</div>
</form>
I want the loading bar appears only when I click the search button while waiting for the response data and go to the results page
Try to add after data:
success: function (test) {
$("#mtg.controller").val('');
$("#success").html(test);
$("#mtg.controller").removeClass("disabled");
}
});
});
});
Also, you can do success: function instead of succes(function for what you already have.

Update model outside of controller

Just starting out on angular, not sure how to update a model out of a controller, or in fact if have my head around exactly what to do. I have an autocomplete field based on ion.autocomplete
HTML
<span ng-controller="IonAutocompleteController">
<label class="item item-input item-stacked-label">
<span class="input-label">Item Description</span>
<ion-autocomplete ng-model="model"
item-value-key="name"
item-view-value-key="view"
items-method="getTestItems(query)"
multiple-select="false"
placeholder="Bread, Milk, Eggs etc .."
items-clicked-method="itemsClicked(callback)"/>
</span>
<button class="button button-block button-royal" ng-click="scan()">Scan</button>
<div class="row">
<div class="col"><b>Item Name</b></div>
<div class="col" ng-model="name"></div>
</div>
Javascript
var myApp = angular.module('myApp', ['ionic','ngCordova','ion-autocomplete']);
myApp.config(['$ionicConfigProvider', function($ionicConfigProvider) {
$ionicConfigProvider.tabs.position('bottom')
}]);
myApp.controller('IonAutocompleteController', function ($scope,$http) {
$scope.model = "";
$scope.callbackValueModel = "";
$scope.getTestItems = function (query) {
console.log(query);
return $http.get('http://192.168.100.100/myApp/products/' + query).
success(function(data, status, headers, config) {
console.log(data);
}).error(function(data, status, headers, config) {
console.log("something went wrong")
});
};
$scope.itemsClicked = function (callback) {
console.log(callback);
$scope.name=callback.item.name;
console.log(callback);
$scope.callbackValueModel = callback;
}
});
What is happening here is the autoselect is grabbing data from a REST server and the results are place in the autocomplete. When the item is selected callback is returned in a json array. I want the callback to be place in ng-model="name" but it is out of the controller. Or I assume that is why it is not updating.
your ng-Model="name" binds to $scope.name in your controller. When data is returned from the REST call, just set $scope.name = data.
Two problems here.
1/ there is a missing </label>.
2/ should be using ng-bind NOT ng-model which is for inputs
You need to populate your view with autocomplete data based on what the success callback returns, not return the $http as an invocation.
$http.get('http://192.168.100.100/myApp/products/' + query).
success(function(data, status, headers, config) {
console.log(data);
// Do whatever you need to do to data before binding it,
//such as extracting a value from the JSON, etc.
$scope.model = data;
}).error(function(data, status, headers, config) {
console.log("something went wrong")
});
};

AngularJS Loses Selected Item on View Reload (data type of parameter lost)

I'm running into an issue in an Angular SPA where a select is losing the selected item when a view is reloaded. The selected item value is correct. This is a typical search/results scenario, so I must be missing something basic.
The angular module (much condensed here) is set up with ui routes and states, which determine the views and controllers to load, etc.:
var DomainApp = angular.module('DomainApp', ['ui.router', 'ui.bootstrap', 'angularValidator']);
// add controllers, services, and factories
DomainApp.controller('ProductsController', ProductsController);
DomainApp.service('ProductsService', ProductsService);
var configFunction = function ($stateProvider, $httpProvider, $locationProvider) {
$stateProvider
.state('productSearch', {
url: '/products',
views: {
"searchView": {
templateUrl: '/Templates/products/Search.html',
controller: ProductsController
}
}
})
.state('productResults', {
url: '/products/Results?categoryID',
views: {
"searchView": {
templateUrl: '/Templates/products/Search.html',
controller: ProductsController
}
}
})
}
configFunction.$inject = ['$stateProvider', '$httpProvider', '$locationProvider'];
DomainApp.config(configFunction);
The products controller:
var ProductsController = function($scope, $stateParams, $state, $location, ProductsService) {
// data for search operations
$scope.searchQuery = {
categoryID: $stateParams.categoryID || 0,
categories: null
};
// init api
$scope.init = function () {
var categoryResult = ProductsService.getCategories(0);
categoryResult.then(function(result) {
if (result.isSuccess) {
$scope.searchQuery.categories = result.data.Items;
} else {
$scope.status.isError = true;
$scope.status.errorMessage = result.message;
}
});
}
}
ProductsController.$inject = ['$scope', '$stateParams', '$state', '$location', 'ProductsService'];
The products service:
var ProductsService = function ($http, $q) {
this.getCategories = function (categoryID) {
var deferredObject = $q.defer();
var results = {
isSuccess: true,
message: '',
data: null
}
$http.get('/api/categories/list/100' + ',' + categoryID).
success(function (data) {
results.data = data;
deferredObject.resolve(results);
}).
error(function (data, status, headers, config) {
results.isSuccess = false;
results.message = 'Could not get Category list:';
for (var i = 0; i < data.length; i++) {
results.message = results.message + ' ' + data[i].Message;
}
deferredObject.resolve(results);
});
return deferredObject.promise;
};
}
ProductsService.$inject = ['$http', '$q'];
And the product search template (view):
<div class="container-fluid searchbar" data-ng-init="init()">
<h2>Product Search</h2>
<div class="row top5">
<div class="col-md-5">
<label for="category">Category:</label><input type="text" class="form-control" maxlength="40" id="categoryID" ng-model="searchQuery.categoryID" />
<select class="form-control" name="category" ng-model="searchQuery.categoryID">
<option value="0">Any</option>
<option ng-repeat="item in searchQuery.categories" value="{{item.CategoryID}}">{{item.CategoryName}}</option>
</select>
</div>
</div>
<div class="row top15">
<div class="col-md-12">
<a class="btn btn-default" ui-sref="productResults({categoryID: searchQuery.categoryID})">Search</a>
</div>
</div>
</div>
In the view, the select values are populated by data-ng-init="init()", and the input box and select dropdown are tied to the same model item ng-model="searchQuery.categoryID".
What happens when the view is loaded after selecting a category, is that the value is lost, and the selection reverts to "Any". The text box has the correct selected value. I verified that the select is bound to the model element, as changing the value in the input changes the selected item in the select. On reload, I can see the select flicker, looks like it has the selected value for a moment then loses it.
Edit: In summary, the selected category is only "lost" as the selected item in the select. The selected category value appears correctly in the url, and in the input textbox. This isn't a reference compare issue as the select option values are item.CategoryID and not the item category object.
What am I doing wrong here? How can the select be detached from the bound value and/or am I setting up the binding wrong?
Incidentally, I also tried ng-options instead of ng-repeat to set up the select, but in that case changing the value in the input had no affect.
This issue is actually a bug in $stateParams, where the data type of the integer is lost, and becomes a string. This issue was supposedly fixed in version 0.2.12 of Angular UI Router, but I'm still seeing the issue in 0.2.13 and have to work around the issue by converting the parameter value back to a number.
The updated products controller with the Number function:
var ProductsController = function($scope, $stateParams, $state, $location, ProductsService) {
// data for search operations
$scope.searchQuery = {
categoryID: Number($stateParams.categoryID) || 0,
categories: null
};
// init api
$scope.init = function () {
var categoryResult = ProductsService.getCategories(0);
categoryResult.then(function(result) {
if (result.isSuccess) {
$scope.searchQuery.categories = result.data.Items;
} else {
$scope.status.isError = true;
$scope.status.errorMessage = result.message;
}
});
}
}
ProductsController.$inject = ['$scope', '$stateParams', '$state', '$location', 'ProductsService'];

Filling a select not firing angular controller

I am trying to fill an HTML select using angular. I tested the API and got something like:
{"Countries":[{"Id":1,"Name":"Andorra"},{"Id":2,"Name":"France"}]}
The HTML is the following:
<form id="form" method="post" ng-submit="submit">
<select ng-model="model.currentCountry" ng-options="country.Id as country.Name for country in model.countries" ng-controller="CountryController">
<option value="">Country</option>
</select>
</form>
Then I have the JS code:
var application = angular.module('Application', []);
application.service('CountryService', function ($http) {
return {
GetList: function () {
return $http.get('api/countries');
}
}
});
application.controller('CountryController', function CountryController($scope, CountryService) {
alert("Country Controller");
$scope.model = {
currentCountry: '',
countries: []
}
CountryService.GetList()
.success(function (data, status, headers, config) {
$scope.model.countries = $scope.model.countries.concat(data)
})
.error(function (data, status, headers, config) { });
});
Somehow not even the alert in CountryController gets fired.
Any idea what am I missing?
In the success handler in your controller you have....
$scope.model.countries = $scope.model.countries.concat(data)
So you are concatting the Countries object from your example JSON, change that to this:
$scope.model.countries = $scope.model.countries.concat(data.Countries)
This way you are concatenating the actual array of countries to your model.countries.
Edit here is an example plnkr to play with

ng-change method not executing

I'm trying to pass the object selected in a to update the data of another object.
Here is the html
<select id="categoryListBox"
ng-model="category.selected"
ng-change="updateCategory(category.selected)"
ng-options="category._id as category.name for category in categories">
</select>
This renders
<select id="categoryListBox"
ng-model="category.selected"
ng-change="updateCategory()"
ng-options="category._id as category.name for category in categories"
class="ng-valid ng-dirty">
<option value="0" selected="selected">Test4</option>
<option value="1">Test5</option>
</select>
Here is my update function
$scope.updateCategory = function(){
console.log('hi');
}
My problem is that right now when the selected item changes the updateCategory method doesn't fires. I would like for whenever the option selected in the <select></select> changes that my $scope.updateCategory method fires. It would also be awesome if I could pass the category selected to this method.
Update here is the my initalization which populates the array categories
$scope.init = function (){
console.log('dfakjsdhf');
console.log(apiUrl);
$scope.category = {};
$scope.subcategory = {};
//$scope.categories = {_id: 1, name:'test'};
$http({ method: 'GET', url: apiUrl + '/categories'}).
success(function (data, status, headers, config) {
$scope.categories = data;
console.log($scope.categories);
}).
error(function (data, status, headers, config) {
console.log('error');
});
};
Just rename your ng-model from category.selected to something else. As per my understanding, In your code there is an ambiguity between ng-options category and ng-model category
<select id="categoryListBox"
ng-model="categorymodel"
ng-change="updateCategory(categorymodel)"
ng-options="category.id as category.name for category in categories">
</select>
DEMO
There is no need to pass the category.selected in your function. In your js controller it will be there in your scope, just use it in your updateCategory() function.
JSFiddle
Html:
<select id="categoryListBox"
ng-model="category.selected"
ng-change="updateCategory()"
ng-options="category.id as category.name for category in categories">
</select>
JS:
$scope.updateCategory = function(){
alert($scope.category.selected);
}

Resources