ng-options in angularjs does not get rebind after change in collection - angularjs

I am using dataFactory for getting collection by making api call.
productApp.factory("productDataFactory", function($http){
return {
getUnits: function() {
return $http.get('/unit').then(function(resp) {
return resp.data; // success callback returns this
});
},
getCommodities: function() {
return $http.get('/commodity').then((resp) => {
return resp.data;
})
}
};
});
I use commodities collection in ng-options to populate options of select element.
<select ng-model='selected_Commodity' ng-change="updateGST()" name="commodity" id="commodity" ng-options = " c as c.commodity_name for c in <%= JSON.stringify(commodities) %> track by c "class="form-control selectpicker" data-size="4" data-live-search="true" data-index="5" >
<option value="" ng-hide='selected_Commodity'>Select Commodity</option>
</select>
I am updating collection on a event. I am getting updated values in log. But It does not get reflected in my view.
var getCommodities = function() {
var deferred = $q.defer();
productDataFactory.getCommodities().then((data) => {
if (data.type === 'success') {
debugger;
console.log("Inside factory ");
console.log(JSON.stringify( data.commodities ));
deferred.resolve(data.commodities);
} else {
// $scope.commodities = [{name : data.type + data.msg}]
deferred.reject([{name : data.type + data.msg}]);
}
})
return deferred.promise;
}
$('#commodityModal').on('hide.bs.modal', function () {
$scope.commodities = []
getCommodities().then((data) => {
$scope.commodities = data
console.log("Inside Hide ");
console.log(JSON.stringify( $scope.commodities ));
$("#commodity").selectpicker('refresh')
console.log("Refreshed");
})
})
Please help me how can I rebind my select elements with updated values.

Put this line inside a timeout like this and add timeout as a dependency
$timeout(function(){
$("#commodity").selectpicker('refresh');
});

Change the ng-options
FROM
ng-options = " c as c.commodity_name for c in <%= JSON.stringify(commodities) %> track by c "
TO
ng-options = " c as c.commodity_name for c in commodities track by c "

Related

Angular 1:Build dropdown box dynamically

I am new to Angular 1,so I am stuck with building a dropdown box dynamically using angular.
Below is my code
var app = angular.module('myApp', []);
app.controller('TestCtrl', function($scope, $http) {
I have created an onchange function getTypeName() and have passed the parameters using get method and retrieved the result as json .
$scope.getTypeName = function (type) {
$http.get('get-type-name',
{ params:
{
type: type
}
}).then(
function(response){
var data = response.data;
for(i = 0; i < data.length; i++) {
//code to build dropdown
}
},
);
}
});
Below is my response,
[
{"id":"001","name":"ABC"},
{"id":"002","name":"DEF"},
{"id":"003","name":"GHI"}
]
I want to build a dropdown box using this response within the get method function success using for loop.Please provide a solution to solve this out.
you do like this
in app.js
$scope.getTypeName = function (type) {
$http.get('get-type-name',
{ params:
{
type: type
}
}).then(
function(response){
$scope.data = response.data;
},
);
}
});
in your html
<select id="ddl" model="ddldata" typeof="text"required>
<option data-ng-repeat="ProjectName in data" value="{{ProjectName.id}}" ng-bind={{ProjectName.name}}">
</select>
You can try this,
$scope.yourOptions = [];
$scope.getTypeName = function (type) {$http.get('get-type-name',
{ params:
{
type: type
}
}).then(
function(response){
var data = response.data;
$scope.yourOptions = data;
},
);
}
});
in html,
<select class="form-control" ng-model="whatever" >
<option ng-repeat="x in yourOptions " value="{{x.id}}">{{x.name}}</option>
</select>
Here is an example of dynamically populating select options from an http get https://plnkr.co/edit/7PS7LBBNZA2cNzMorrB9?p=preview
<select ng-model="selectedItem">
<option ng-repeat="o in options">{{o.name}}</option>
</select>
$scope.getTypeName = function() {
$http.get('https://jsonplaceholder.typicode.com/users').then(
function(result) {
$scope.options = result.data;
},
function(error) {
console.log(error);
}
);
};

Populating a dropdownlist with AngularJS

I want to populate a dropdownlist with values from a table I created called Venues. This table has only two things in it, the Venue Id and Name.
I created a Code First Entity Data Model from the database that holds the table Venues and I created this method in my controller:
public JsonResult GetVenues()
{
using (ReservationsModel dc = new ReservationsModel())
{
var v = dc.Venues.OrderBy(a => a.Name).ToList();
return new JsonResult { Data = v, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
then in my script i added:
$scope.selectedVenue = null;
$scope.venues = [];
$http.get("/home/getvenues").success(function (data) {
angular.forEach(data, function (item) {
venues.push(item.Name);
});
$scope.list = venues;
}).error(function (status) {
alert(status);
});
$scope.selectedVenue = $scope.venues[i].Name;
and in my view I have:
<select ng-model="selectedVenue" ng-options="item in venues">
<option value="">-- Select Venue --</option>
</select>
I came from these guides:
http://www.dotnetawesome.com/2016/04/implement-event-scheduler-calendar-angularjs.html
How can I populate a select dropdown list from a JSON feed with AngularJS?
https://jsfiddle.net/pravinmagar/Ljgk8oy0/
Let's see your code.(check the comments)
$scope.selectedVenue = null;
$scope.venues = [];
$http.get("/home/getvenues").success(function (data) {
angular.forEach(data, function (item) {
// this should be $scope.venues, not just venues
venues.push(item.Name);
});
// you don't need another scope variable
$scope.list = venues;
}).error(function (status) {
alert(status);
});
// as $scope.venues is an array of Names, $scope.selectedVenue = $scope.venues[i] is enough
$scope.selectedVenue = $scope.venues[i].Name;
So,
$scope.venues = [];
$http.get("/home/getvenues").success(function (data) {
angular.forEach(data, function (item) {
$scope.venues.push(item.Name);
});
}).error(function (status) {
alert(status);
});
// if i has declared a value somewhere in your code, then
$scope.selectedVenue = $scope.venues[i];
and in template,
<select ng-model="selectedVenue">
<option value="">Select Venue</option>
<option ng-repeat="venue in venues" ng-value="venue">{{venue}}</option>
</select>
Your html part is ok, just need following modification in controller JS:
access venues like $scope.venues while pushing
assign default selected inside .success because http.get() is async.
Code:
$scope.selectedVenue = null;
$scope.venues = [];
$http.get("/home/getvenues").success(function (data) {
angular.forEach(data, function (item) {
$scope.venues.push(item.Name);
});
$scope.selectedVenue = $scope.venues[i].Name; // i must be declared in your js
}).error(function (status) {
alert(status);
});

No popup window with AngularJS and typeahead

I have a problem with the typeahead directive. I try to get datas from my datas from my service via $http.get.
In the console output I can see that my datas are coming from the service but I don't get the popup window of the results.
Here is my code:
Html Template:
<input type="text" class="form-control" placeholder="Kundensuche" ng-model="selectedCompany" typeahead="c for c in companies($viewValue)" typeahead-no-results="noResults" typeahead-min-length="3">
Service:
var _search = function (route, id) {
return $http.get(serviceBase + 'api/' + route + '/search/' + id);
};
serviceHelperFactory.search = _search;
Controller:
$scope.companies = function (val) {
var output = [];
var promise = serviceHelper.search('companies', val);
promise.then(function (result) {
result.data.forEach(function (company) {
output.push(company.companyName);
//output.push(company);
});
console.log(output);
}, function (error) {
adminInvoiceService.serviceErrorMessage(error);
});
return output;
}
Thanks!
Ok, I fixed it!
For all with the same problem here is my solution!
$scope.companies = function (val) {
return $http.get('http://localhost:5569/api/companies/search/'+val).then(function (res) {
var companies = [];
console.log(companies);
res.data.forEach(function (item) {
companies.push(item);
});
console.log(companies);
return companies;
});
};

Set dropdown value using angular js

I want to set the dropdown value on basis of json result returned by mvc controller.
Code behind (mvc controller)
public ActionResult GetProject(int Id)
{
using (ManagementSystemEntities db = new ManagementSystemEntities())
{
return Json(db.SelectProject(Id).ToList(), JsonRequestBehavior.AllowGet);
}
}
Above lines are working correctly. It returns list of projects.
List returned :
Id Title
1 test
2 test2
I want to select dropdown value as "test" by its value which is Id = 1
HTML >>
<select ng-options="project.Title for project in projectList" id="ddlProject" ng-model="selectedProject">
<option value="">-- Select Project --</option>
<option data-ng-repeat="project in projectList" value="{{project.Id}}"> {{project.Title}}</option>
</select>
There is no issue which is related to angular loading. Everything working fine. Only need is to set the dropdown value on basis of ajax result.
Ajax Call (angular code) >>
Code for Populating dropdown options : (Working fine)
$http.get(service_url + "Project/GetProject", { params: { "id": 0 } })
.success(function (response) {
if (response.length < 1) {
// No Record
}
else {
$scope.projectlist = response;
}
})
.error(function (data) {
fnsuccessmodal("error in load", "error");
});
Code for set value in dropdown :
$http.get(service_url + "Project/GetProject", { params: { "Id": 1 } })
.success(function (response) {
if (response.length < 1) {
// No Record
}
else {
$.each(response, function (index, item) {
//console.log(item.ProjectId); it is displaying 1 as in console screen I am only getting project which have Id equal to 1.
$scope.selectedProject = $scope.projectList[item.ProjectId]; // This line not working
});
}
})
.error(function (data) {
fnSuccessModal("Error in Load", "Error");
});
Please help.
This is some recomendations. If you don´t want them go to the (BUT) bellow. First you should return a list if you going to pass a collection, and just one item if you want to search by id and the id is the primary key of the project.
I have write this here so there are possible some errors.
public ActionResult GetProject(int? Id)
{
using (ManagementSystemEntities db = new ManagementSystemEntities())
{
return Json( id.HasValue ? db.SelectProject(Id).FirstOrDefault() : db.SelectAllProjects().ToList(), JsonRequestBehavior.AllowGet);
}
}
this way to get the list you can change your code to
$http.get(service_url + "Project/GetProject", { })
.success(function (response) {
if (response.length < 1) {
// No Record
}
else {
$scope.projectlist = response;
}
})
.error(function (data) {
fnsuccessmodal("error in load", "error");
});
to get the selected project, by your logic
$http.get(service_url + "Project/GetProject", { params: { "Id": 1 } })
.success(function (response) {
if (response) {
$scope.selectedProject = response;
});
}
})
.error(function (data) {
fnSuccessModal("Error in Load", "Error");
});
for the markup, you should not have an an ng-options inside ng-repeat
<select ng-options="project as project.Title for project in projectList track by project.Id" id="ddlProject" ng-model="selectedProject">
<option value="">-- Select Project --</option>
</select>
BUT if you don´t want to change the things that i talked about just change this and it shoul work. It´s your choice
$http.get(service_url + "Project/GetProject", { params: { "Id": 1 } })
.success(function (response) {
if (response.length < 1) {
// No Record
}
else {
$.each(response, function (index, item) {
//console.log(item.ProjectId); it is displaying 1 as in console screen I am only getting project which have Id equal to 1.
$scope.selectedProject = item:
});
}
})
.error(function (data) {
fnSuccessModal("Error in Load", "Error");
});
and the markup you have to introduce a track by so
<select ng-options="project as project.Title for project in projectList track by project.Id" id="ddlProject"
ng-model="selectedProject">
<option value="">-- Select Project --</option>
</select>
here is a plunker that i created with my opinion where the http.get where replaced by timeouts
here you can find documentation for ngRepeat track by
Best,

Change in data made by $http inside a factory is not reflected to the DOM

I'm trying to create a dynamic form based on an object.
For example: I'd like that generated select boxes will contain options if given, otherwise a factory will fetch them using ajax, something like this:
Markup:
<select ng-repeat="select in selects"
ng-init="options = refactor.options(select)"
ng-options="option in options">
</select>
Controller:
myApp.controller('MyCtrl', function($scope, refactor) {
$scope.refactor = refactor;
$scope.selects = [
{ text: "Country", value="chosen.country", options=["France", "England"] },
{ text: "Gender", value="chosen.gender", options="/gender" }
]
});
Factory:
myApp.factory('refactor', function($scope, $http) {
return {
options: function(select) {
if(typeof(select.options) === 'object') { return select.options };
// otherwise assume select.options is
// a path to fetch options by ajax:
$http.get(select.options).success(function(data) {
select.options = data; // data == ['male', 'female']
});
return []; // placeholder until promise is fulfilled
}
}
})
The data ( $scope.selects ) gets updated as expected, yet the DOM is not, which probably means refactor.options() is not being invoked again in response to the change. I tried to force an update by passing the scope object to the factory and invoke $apply on it, but it doesn't work.
What am I missing?
You need to use ng-init="data = refactor.options(select)" so after getting data from ajax data would be filled up with options then you could use ng-options as instead of ng-options="option in data.options".
Markup
<select ng-repeat="select in selects"
ng-init="data = refactor.options(select)"
ng-options="option in data.options">
</select>
You should try this
myApp.factory('refactor', function($scope, $http) {
return {
options: function(select) {
var menuItems={
options:[]
}
if(typeof(select.options) === 'object'){
menuItems.options=select.options
};
// otherwise assume select.options is
// a path to fetch options by ajax:
$http.get(select.options).success(function(data) {
select.options = data;
menuItems.options=data;// data == ['male', 'female']
});
return menuItems; // placeholder until promise is fulfilled
}
}
});
Then inside your view it should go like this
<select ng-repeat="select in selects"
ng-init="menuItems= refactor.options(select)"
ng-options="option in menuItems.options">
</select>

Resources