Get attributes associated with a selected item in a drop down list AngularJS - angularjs

I'm building an app using ASP.NET Web API with AngularJS and I'm new to these frameworks. I have a drop down list which display data from the API. When I select an element from the drop down, I want to get the other attributes associated with it.
Here's the API
[Route("CustomerRecords")]
public List<Customer> Get()
{
return new List<Customer>()
{
new Customer { CID=1, Name="Bruce Wayne", PIN="1234", Bal=1000000, cardStatus= 0 }
,new Customer { CID=2, Name="Tony Stark", PIN="2246", Bal=900000, cardStatus= 0 }
,new Customer { CID=3, Name="Jon Snow", PIN="2398", Bal=3000, cardStatus= 1 }
,new Customer { CID=4, Name="Rustin Cohle", PIN="7549", Bal=450000, cardStatus= 2 }
};
}
}
public class Customer
{
public int CID { get; set; }
public string Name { get; set; }
public string PIN { get; set; }
public int Bal { get; set; }
public int cardStatus { get; set; }
}
here's the module, the service and the factory method
var customerAppModule = angular.module("customerApp", []);
customerAppModule.controller('CustomerCtrl', function ($scope, CustomerService)
{
getCustomerRecords();
function getCustomerRecords() {
CustomerService.getCustomers()
.success(function (data) {
console.log(data);
$scope.customers = data;
})
.error(function (data, status) {
console.error('failure loading the customer record', status, data);
$scope.customers = {};
});
}
});
customerAppModule.factory('CustomerService', ['$http', function ($http) {
var customerService = {};
var urlBase = 'http://localhost:51701/Customer';
customerService.getCustomers = function () {
return $http.get(urlBase + '/CustomerRecords');
};
return customerService;
}]);
and here is my drop down
<select ng-change="getCustomers(details)" ng-model="details">
<option ng-repeat="customer in customers" value="{{customer.CID}}">{{customer.Name}}</option>
</select>
So, only the names appear in my drop down, but if I select a particular name, I want to be able to get its other attributes

Your function getCustomers inside the controller should have all the details as a parameter, since you are passing it,
$scope.getCustomers = function(details){
//this has all the details associated with id (details);
}

use select.js library and try like following
<ui-select ng-model="model" append-to-body="true">
<ui-select-match>
<span ng-bind="$select.selected.name"></span>
</ui-select-match>
<ui-select-choices repeat="item in modelList" >
<div ng-bind="item.name" ng-click="selectValue(item)"></div>
</ui-select-choices>
</ui-select>

Related

POST dynamically added Lists to Controller as Json and redirect view

Description
I'm am creating a dynamic table where the user can select regions in a dropdown lists. On "add" the user can also add new table rows with region dropdown lists included. On POST, a list of Regions should be posted to the controller where it´s being saved to the SavingPlan model.
Problem
Ajax is returning null to my controller even though I have saved selected option-data to string arrays which is being posted to the controller.
Addition
I am fairly new to ASP.NET MVC so please have that in mind when commenting. I am open minded towards doing things differently but I´d very much appreciate I someone would be able to guid me and my code in the right direction.
Region Model
public class Region
{
public int Id { get; set; }
public string Name { get; set; }
}
Saving Plan Model
public SavingPlan()
{
}
public SavingPlan(List<Region> regionList)
{
RegionList = regionList;
}
public int Id { get; set; }
public ApplicationUser AssessmentUser { get; set; }
public IEnumerable<Region> RegionLookUp { get; set; }
public bool IsActive { get; set; }
public byte RegionId { get; set; }
public Region Region { get; set; }
public List<Region> RegionList { get; set; }
}
SavingPlan - ViewModel
public class SavingPlan
{
public SavingPlan()
{
}
public SavingPlan(List<Region> regionList)
{
RegionList = regionList;
}
public int Id { get; set; }
public ApplicationUser AssessmentUser { get; set; }
public IEnumerable<Region> RegionLookUp { get; set; }
public bool IsActive { get; set; }
public byte RegionId { get; set; }
public Region Region { get; set; }
public List<Region> RegionList { get; set; }
}
Controller Action GET - NewSavingPlan
public ActionResult NewSavingPlan()
{
SavingPlanAssessmentView viewModel = new SavingPlanAssessmentView();
viewModel.SavingPlan = new SavingPlan();
var regions = _context.Regions
.ToList();
viewModel.RegionLookUp = regions;
return View(viewModel);
}
Controller Action POST - Save SavingPlan
[HttpPost]
public JsonResult SaveList(string RegionList)
{
var urlBuilder = new UrlHelper(Request.RequestContext);
var url = urlBuilder.Action("Index", "Assessments");
string[] arr = RegionList.Split(',');
foreach (var item in arr)
{
var region = item;
}
return Json(new { status = "success", redirectUrl = Url.Action("Index","Home") });
}
SavingPlan Partial View
#model BBRG.ViewModels.SavingPlanAssessmentView
<h2>#Model.Heading</h2>
#*#using (Html.BeginForm("Save", "Assessments", FormMethod.Post))
{*#
#*#Html.AntiForgeryToken()
#Html.HiddenFor(m => m.Id)*#
<legend>Saving Plan</legend>
<table id="regionTable" class="table table-striped">
<thead>
<tr>
<td>Region</td>
<td> <button id="add" type="button" class="btn btn-link">Add</button></td>
<td></td>
</tr>
</thead>
<tbody>
<tr id="regionRow_1">
<td>
#Html.DropDownListFor(m => m.RegionId, new SelectList(Model.RegionLookUp, "Id", "Name"), "Select Region", new { #class = "form-control Region", id = "Region_1", type="string", name = "Region", selected="false" })
</td>
<td>
<button data-region-id="#Model.RegionId" id="deleteRegion" type="button" class="btn btnDeleteRegion btn-link btn-xs btn" btn-xs>remove</button>
</td>
</tr>
</tbody>
</table>
<hr />
<p>
#Html.HiddenFor(m => m.Id)
<button data-saving-id="#User.Identity" onclick="saveRegion()" type="submit" calss="btn btn-default js-toggle-save">Save</button>
</p>
Jquery - Add new table row with dropdownlist
$(document).ready(function () {
var counter = 2;
$(function () {
$('#add').click(function () {
$('<tr id="regionRow_' + counter + '">'
+ '<td>'
+ '<select type="text" value="RegionId" name="Region" id="Region_'+ counter+'" class="form-control Region" " >'
+ $(".Region").html()
+ '</select>'
+ '</td>'
+ '<td>'
+ '<button data-region-id= id="deleteRegion" type="button" class="btn btnDeleteRegion btn-link btn-xs btn" btn-xs>remove</button>'
+ '</td>'
+ '</tr>').appendTo('#regionTable');
counter++;
return false;
});
});
});
Jquery and .ajax for POST
{
<script src="~/Scripts/SavingPlanScripts.js"></script>
<script>
var saveRegion = (function () {
var array = [];
var commaSeperated = "";
var count = 1;
$("#regionTable tbody .Region").each(function (index, val) {
var regionId = $(val).attr("Id");
var arr = regionId.split('_');
var currentRegionId = arr[1];
var isSelected = $(".Region option").is(':selected', true);
if (isSelected) {
array.push(currentRegionId);
}
count++;
});
if (array.length != 0) {
commaSeperated = array.toString();
$.ajax({
type: "POST",
dataType: "json",
contentType: "/application/json",
url: "/SavingPlans/SaveList",
data: { "RegionList": commaSeperated },
success: function (json) {
if (json.status == "success") {
window.location.href = json.redirectUrl;
};
}
});
};
});
</script>
}```
I found the solution to my problem, I forgot to stringify my .ajax data. If anyone still want to provide me with some constructive input, please don´t hesitate.
$.ajax({
url: "../SavingPlans/SaveList",
data: JSON.stringify({ RegionId: commaSeperated }),
type: "POST",
dataType: "json",
contentType: 'application/json; charset=utf-8',
success: function (json) {
if (json.status == "success") {
window.location.href = json.redirectUrl;
};
}
});

How to get the values of the child element from the parent element in angularjs

I have two database tables with one being the parent and the other being the child. The parent table has a reference to the child table. Database table was generated using code-first approach with the data models are below:
[Table("Family")]
public partial class Family
{
public int Id { get; set; }
public string Surname { get; set; }
public string FirstName { get; set; }
public int RoleId { get; set; }
public int FuId { get; set; }
public int RiskAreaId { get; set; }
public int LocationId { get; set; }
public DateTime CreatedDate { get; set; }
[ForeignKey("RoleId")]
public virtual Role Role { get; set; }
[ForeignKey("FuId")]
public virtual FamilyUnit FamilyUnit { get; set; }
[ForeignKey("RiskAreaId")]
public virtual RiskArea RiskArea { get; set; }
[ForeignKey("LocationId")]
public virtual Location Location { get; set; }
}
And the FamilyUnit table i below:
[Table("FamilyUnit")]
public partial class FamilyUnit
{
public int Id { get; set; }
[Column(TypeName = "varchar")]
[StringLength(50)]
[Required]
public string FamilyUnitName { get; set; }
public virtual IEnumerable<Family> Families { get; set; }
}
I then created a webAPI project so my project can consume the APIs. My Api is shown below:
[EnableCors("*", "*", "*")]
public class FamilyUnitController : ApiController
{
FamilyUnitBs familyUnitObjBs;
public FamilyUnitController()
{
familyUnitObjBs = new FamilyUnitBs();
}
[ResponseType(typeof(IEnumerable<FamilyUnit>))]
public IHttpActionResult Get()
{
var famUnits = familyUnitObjBs.GetALL();
return Ok(famUnits);
}
[ResponseType(typeof(FamilyUnit))]
public IHttpActionResult Get(int id)
{
FamilyUnit familyUnit = familyUnitObjBs.GetByID(id);
if (familyUnit != null)
return Ok(familyUnit);
else
return NotFound();
}
[ResponseType(typeof(FamilyUnit))]
public IHttpActionResult Delete(int id)
{
FamilyUnit familyUnit = familyUnitObjBs.GetByID(id);
if (familyUnit != null)
{
familyUnitObjBs.Delete(id);
return Ok(familyUnit);
}
else
{
return NotFound();
}
}
}
I then created another project called for the front-end of the application to consume the API methods.
Below is the angularjs controller with the factory service
appEIS.factory('familyMgmtService', function ($http,$rootScope) {
famMgmtObj = {};
famMgmtObj.getAll = function () {
var Fams;
Fams = $http({ method: 'Get', url:$rootScope.ServiceUrl+ 'FamilyUnit' }).
then(function (response) {
return response.data;
});
return Fams;
};
famMgmtObj.createFamily = function (fam) {
var Fam;
Fam = $http({ method: 'Post', url:$rootScope.ServiceUrl+ 'Family', data: fam }).
then(function (response) {
return response.data;
}, function(error) {
return error.data;
});
return Fam;
};
famMgmtObj.deleteFamilyById = function (eid) {
var Fams;
Fams = $http({ method: 'Delete', url:$rootScope.ServiceUrl+ 'FamilyUnit', params: { id: eid } }).
then(function (response) {
return response.data;
});
return Fams;
};
famMgmtObj.getFamilyByFuId = function (fid) {
var Fams;
console.log(fid);
Fams = $http({ method: 'Get', url: $rootScope.ServiceUrl + 'Family', params: { id: fid } }).
then(function (response) {
return response.data;
});
return Fams;
};
return famMgmtObj;
});
appEIS.controller('familyMgmtController', function ($scope, familyMgmtService, utilityService, $window) {
$scope.Sort = function (col) {
$scope.key = col;
$scope.AscOrDesc = !$scope.AscOrDesc;
};
familyMgmtService.getAll().then(function (result) {
$scope.Fams = result;
console.log(result);
});
$scope.CreateFamily = function (Fam, IsValid) {
if (IsValid) {
$scope.Fam.Password = utilityService.randomPassword();
familyMgmtService.createFamily(Fam).then(function (result) {
if (result.ModelState == null) {
$scope.Msg = " You have successfully created " + result.FamilyId;
$scope.Flg = true;
utilityService.myAlert();
$scope.serverErrorMsgs = "";
familyMgmtService.getAll().then(function (result) {
$scope.Fams = result;
});
}
else {
$scope.serverErrorMsgs = result.ModelState;
}
});
}
};
$scope.DeleteFamilyById = function (Fam) {
if ($window.confirm("Do you want to delete Family with Id:" + Fam.FamilyId + "?")) {
familyMgmtService.deleteFamilyById(Fam.FamilyId).then(function (result) {
if (result.ModelState == null) {
$scope.Msg = " You have successfully deleted " + result.FamilyId;
$scope.Flg = true;
utilityService.myAlert();
familyMgmtService.getAll().then(function (result) {
$scope.Fams = result;
});
}
else {
$scope.serverErrorMsgs = result.ModelState;
}
});
}
};
$scope.GetFamilyByFuId = function (Fam) {
familyMgmtService.getFamilyByFuId(Fam.fid).then(function (result) {
console.log(result);
$scope.Fams = result;
});
};
$scope.CreateMultiFamily = function () {
var file = $scope.myFile;
var uploadUrl = "http://localhost:60736/api/Upload/";
utilityService.uploadFile(file, uploadUrl, $scope.eid).then(function (result) {
$scope.image = result;
});
};
});
The family unit is displaying well in an accordion list but the various families are not getting displayed using the familyUnit Id as shown below:
<div class="panel-body">
<div dir-paginate="emp in Fams | filter:search | orderBy:key:AscOrDesc | itemsPerPage:10" class="wrapper center-block">
<div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="heading{{emp.Id}}">
<h4 class="panel-title">
<div role="button" data-toggle="collapse" data-parent="#accordion" href="#collapse{{emp.Id}}" aria-expanded="true" aria-controls="collapse{{emp.Id}}">
{{emp.FamilyUnitName}}
</div>
</h4>
</div>
<div id="collapse{{emp.Id}}" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="heading{{emp.Id}}">
<div class="panel-body">
<div ng-repeat="f in emp.Families">{{f.FirstName}} - {{f.Surname}}</div>
</div>
</div>
</div>
</div>
</div>
Based on the discussion in the comments, this issue looks like the issue with data and not with the front-end (yet).
You need to load the Families details while getting the FamilyUnit in your Get(int id) method. There are two ways through which you can do the early loading.
Use Include with Linq, like:
var familyUnit = familyUnitObjBs.FamilyUnits
.Include(fu => fu.Families)
.Where (fu +. fu.Id == Id)
.ToList();
The second option could be using the early loading by removing the virtual from your data structure, which might be an issue if you plan to add more methods or maybe if you have test cases to override, still, it will look like:
[Table("FamilyUnit")]
public partial class FamilyUnit
{
public int Id { get; set; }
[Column(TypeName = "varchar")]
[StringLength(50)]
[Required]
public string FamilyUnitName { get; set; }
public IEnumerable<Family> Families { get; set; }
}
You can find more details about lazy loading and early loading at:
https://msdn.microsoft.com/en-us/library/jj574232(v=vs.113).aspx
EDIT:
1. You can use strong type instead of var for familyUnit:
List<FamilityUnit> familyUnit= familyUnitObjBs.FamilyUnits
.Include(fu => fu.Families)
.Where (fu +. fu.Id == Id)
.ToList();
Get the list instead of FirstOrDefault() if you need whole list:
return db.Familiies.Where(x => x.FuID == id).ToList();

System.NullReferenceException in controller ASP.Net MVC

Working with (simple bowling game web app) where there are two text boxes and one submit button.
text box 1 = FirstRoll ,text box 2 = SecondRoll
User enter two numbers and cilck submit button then displays a score.
Issue : Getting System.NullReferenceException in Submit action method. Why frame is empty in first instance?
Controller
[HttpPost]
public JsonResult Submit(Frame[] _frames)
{
int result= 0;
var objBowlingScore = new GameEngineService();
foreach(var frame in _frames)
{
result = objBowlingScore.CalculateFrameScore(frame);
}
return Json(objBowlingScore);
}
Model
server side check validations are removed for code readability
public class Frame
{
public int FrameId { get; set; }
public int FirstRoll { get; set; }
public int SecondRoll { get; set; }
public int ThirdRoll { get; set; }
public int Score { get; set; }
}
View
<p>1st Roll: #Html.EditorFor(m => m.FirstRoll)</p>
<p>2nd Roll: #Html.EditorFor(m => m.SecondRoll)</p>
<button id="submitButton" class="btn btn-primary btn-lg">Submit Score</button>
<p><label>The current frame is : </label><label id="lblFrameCount"></label></p>
<p><label>The current score is : </label><label id="lblTotalScore"></label></p>
#section DocumentReady {
<script type="text/javascript">
var bowlingData = { "frames": [] };
$('#submitButton').click(function (e) {
var temp = {
"firstroll": $("#FirstRoll").val(),
"secondroll": $("#SecondRoll").val()
};
bowlingData.frames.push(temp);
var element = this;
$.ajax({
url: "/Home/Submit",
type: "POST",
data: JSON.stringify(bowlingData),
dataType: "json",
traditional: true,
contentType: "application/json; charset=utf-8",
success: function (data) {
$("#lblTotalScore").text(data.Score);
$("#FirstRoll").val("");
$("#SecondRoll").val("");
},
error: function () {
alert("An error has occured!!!");
}
});
});
</script>
Service
....
public int CalculateFrameScore(Frame _frame)
{
return _frame.FirstRoll + _frame.SecondRoll + _frame.ThirdRoll;
}
....
The issue was the parameter name in the Submit method didn't match with the parameter used in the jQuery event handler.
_frames should be frames. (i.e.
Was
public JsonResult Submit(Frame[] _frames))
Should be
public JsonResult Submit(Frame[] frames))

Http post in angularjs sends empty object

I'm learning AngularJS and I've been trying to send data from a controller using $http.post to a web api, but I keep getting empty data.
Any idea why? Tks in advance
This is my angular code
<!doctype html>
<html>
<head>
<title>Product Add</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
</head>
<body ng-app="ProductAdd">
<script>
var app = angular.module('ProductAdd', []);
app.controller('ProductAddController', ['$scope', '$http', function ($scope, $http) {
$scope.submit = function () {
if ($scope.Name) {
var product = {
"Name": $scope.Name,
"Category": $scope.Category,
"Price": $scope.Price
}
$http.post('http://localhost:1110/api/product', JSON.stringify(product)).
success(function () {
alert('Product Added Successfully');
}).
error(function () {
alert("erro");
});
}
};
}]);
</script>
<h2>Add New Product</h2>
<form ng-submit="submit()" ng-controller="ProductAddController">
<div>Name:<input type="text" ng-model="Name" required></div><br />
<div>Category:<input type="text" ng-model="Category" required> </div> <br />
<div>Price:<input type="text" ng-model="Price"> </div> <br />
<div> <input type="submit" id="productsubmit" value="Submit" /></div> <br />
</form>
</body>
</html>
This is my Web Api controller code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
using System.Web.Http.Cors;
using Product_API.Models;
namespace Product_API.Controllers
{
[EnableCors("http://localhost:3442", "*","*")]
public class ProductController : ApiController
{
public static Lazy<List<Product>> Products = new Lazy<List<Product>>();//Static variable use only for demo, don’t use unless until require in project.
public static int PgaeLoadFlag = 1; // Page load count.
public static int ProductId = 4;
public ProductController()
{
if (PgaeLoadFlag == 1) //use this only for first time page load
{
//Three product added to display the data
Products.Value.Add(new Product { ID = 1, Name = "bus", Category = "Toy", Price = 200 });
Products.Value.Add(new Product { ID = 2, Name = "Car", Category = "Toy", Price = 300 });
Products.Value.Add(new Product { ID = 3, Name = "robot", Category = "Toy", Price = 3000 });
PgaeLoadFlag++;
}
}
// GET api/product
public List<Product> GetAllProducts() //get method
{
//Instedd of static variable you can use database resource to get the data and return to API
return Products.Value; //return all the product list data
}
// GET api/product/5
public IHttpActionResult GetProduct(int id)
{
Product product = Products.Value.FirstOrDefault(p => p.ID == id);
return product == null ? (IHttpActionResult) NotFound() : Ok(product);
}
**// POST api/product
[AcceptVerbs("OPTIONS")]
public void ProductAdd(Product product) //post method
{
product.ID = ProductId;
Products.Value.Add(product);
ProductId++;
}**
}
}
and this is my model
namespace Product_API.Models
{
public class Product
{
public int ID { get; set; }
public string Name { get; set; }
public string Category { get; set; }
public int Price { get; set; }
}
}
Just don't stringify your object:
$http.post('http://localhost:1110/api/product', product)

I just want to pass the list to the asp.net web api using angularjs

I'm working on EAV database pattern.
My model is like this:
public class LeadsModel
{
public int? CompId { get; set; }
public int LeadID { get; set; }
public string LeadName { get; set; }
public string source { get; set; }
public string status { get; set; }
public int UserId { get; set; }
[Required]
public List<AttributesModel> AList { get; set; }
}
My view is like this. In view I'm fetching the list of attributes and I want to post back the using angularjs.
<div class="form-group" ng-repeat="At in Attributes" >
<label for="{{At.Attri}}" class="col-md-4 control-label">{{At.Attri}}</label>
<div class="col-md-8">
#*<input type="hidden" name="{{At.AID}}" data-ng-model="newLead.NewAlist" />*#
<input type="text" class="form-control" id="{{At.Attri}}" name="{{At.Attri}}" pl placeholder="Enter {{At.Attri}}" data-ng-model="newLead.AList.AttriValue" ng-blur="AddItemToList(newLead.Alist.AttriValue)" />
</div>
</div>
My Angular code is like this
$scope.add = function ()
{
$scope.loading = true;
this.newLead.AList = $scope.listt;
$http.post('/api/Leads/Posttbl_Lead', this.newLead).success(function (data) {
alert("Added Successfully!!");
$scope.loading = false;
$scope.addLMode = false;
})
.error(function () {
$scope.error = "An Error has occured while loading posts!";
$scope.loading = false;
});
}
and my web api controller is like this
public IHttpActionResult Posttbl_Lead(LeadsModel tbl_Lead)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
tbl_Lead newLead = new tbl_Lead();
newLead.LeadName = tbl_Lead.LeadName;
newLead.source = tbl_Lead.source;
newLead.status = tbl_Lead.status;
newLead.LeadName = tbl_Lead.LeadName;
newLead.CompId = tbl_Lead.CompId;
db.tbl_Lead.Add(newLead);
db.SaveChanges();
return CreatedAtRoute("DefaultApi", new { id = tbl_Lead.LeadID }, tbl_Lead);
}
Use this code to post your newLead of AngularJs to tbl_Lead of your API contoller. This is the complementary link for You to pass the list/ array object to You API.
$http({
contentType: "application/json; charset=utf-8",//required
method: "POST",
url: '/api/Leads/Posttbl_Lead',
dataType: "json",//optional
data:{ "tbl_Lead": newLead },
async: "isAsync"//optional
})
.success( function (response) {
alert('Saved Successfully.');
})
.error(function () {
$scope.error = "An Error has occured while loading posts!";
$scope.loading = false;
});
Edit-1
Below mentioned is the way to send AList inside LeadsModel to your api.
LeadsModel to send onto the server via API.
{
CompId=compId,
LeadID=leadID,
AList=[{FirstObject=firstObject},{SecondObject=secondObject}]
}

Resources