ng-change event not firing inside the loop - angularjs

function friendControllerTest($scope, $http) {
$scope.loading = true;
$scope.addMode = false;
$scope.countryList = [];
$scope.stateList = [];
function getAllCountry() {
$http({
method: 'Get',
url: '/Home/GetCountry'
}).success(function (data) {
$scope.countryList = data;
}).error(function () {
$scope.errorMessage = 'Not found';
});
}
function getStatebyCountryId(Id) {
$scope.stateList = null;
if (Id) { // Check here country Id is null or not
$http({
method: 'POST',
url: '/Home/GetStateByCountryId/',
data: JSON.stringify({ CountryId:Id })
}).success(function (data) {
$scope.stateList = data;
}).error(function (data) {
alert(data.message);
$scope.message = 'not found';
});
}
else {
$scope.stateList = null;
}
}
$scope.GetStatesList = function (id) {
if (id) { // Check here country Id is null or not
$http({
method: 'POST',
url: '/Home/GetStateByCountryId/',
data: JSON.stringify({ CountryId: id })
}).success(function (data) {
$scope.stateList = data;
}).error(function (data) {
alert(data.message);
$scope.message = 'not found';
});
}
else {
$scope.stateList = null;
}
}
$scope.myMethod = function () {
var text = $scope.newfriend.SearchText;
$http.get('../Home/GetFriendsList', { params: { 'text': text } }).success(function (data) {
$scope.friends = data;
})
.error(function () {
$scope.error = "An Error has occured while loading posts!";
});
}
$http.get('../Home/GetFriendsList').success(function (data) {
alert("list called")
$scope.friends = data;
$scope.loading = false;
})
.error(function () {
$scope.error = "An Error has occured while loading posts!";
$scope.loading = false;
});
$scope.toggleAdd = function () {
$scope.addMode = !$scope.addMode;
if ($scope.addMode) {
getAllCountry();
}
};
$scope.toggleEdit = function () {
this.friend.editMode = !this.friend.editMode;
getAllCountry();
if (this.friend.Country.Id > 0)
getStatebyCountryId(this.friend.Country.Id);
};
$scope.add = function () {
$scope.loading = true;
var newfriend = {
firstname: $scope.newfriend.firstname,
lastname: $scope.newfriend.lastName,
address: $scope.newfriend.address,
postalcode: $scope.newfriend.PostalCode,
notes: $scope.newfriend.Notes,
CountryId: $scope.newfriend.Country.Id,
StateId: $scope.newfriend.State.Id
}
$http.post('../Home/AddFriends', newfriend).success(function (data) {
alert("Added Successfully!!");
$scope.addMode = false;
$scope.friends.push(data);
$scope.loading = false;
$scope.newfriend = "";
}).error(function (data) {
$scope.error = "An Error has occured while Adding Friend! " + data;
$scope.loading = false;
});
};
$scope.save = function () {
$scope.loading = true;
var frien = this.friend;
$http.put('../Home/EditFriend', frien).success(function (data) {
alert("Saved Successfully!!");
frien.editMode = false;
$scope.loading = false;
}).error(function (data) {
$scope.error = "An Error has occured while Saving Friend! " + data;
$scope.loading = false;
});
};
$scope.deletefriend = function () {
$scope.loading = true;
var friendid = this.friend.Id;
$http.delete('../Home/RemoveFriend/' + friendid).success(function (data) {
alert("Deleted Successfully!!");
$.each($scope.friends, function (i) {
if ($scope.friends[i].Id === friendid) {
$scope.friends.splice(i, 1);
return false;
}
});
$scope.loading = false;
}).error(function (data) {
$scope.error = "An Error has occured while Saving Friend! " + data;
$scope.loading = false;
});
};
}
<html data-ng-app="" data-ng-controller="friendControllerTest">
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")
</head>
<body>
<div class="container">
<strong class="error">{{ error }}</strong>
<div id="mydiv" data-ng-show="loading">
<img src="Images/ajax-loader1.gif" class="ajax-loader" />
</div>
<p data-ng-hide="addMode">
<a data-ng-click="toggleAdd()" href="javascript:;" class="btn btn-primary">Add New
</a>
</p>
<form name="addFriend" data-ng-show="addMode" style="width: 600px; margin: 0px auto;">
<label>FirstName:</label><input type="text" data-ng-model="newfriend.firstname" required />
<label>LastName:</label><input type="text" data-ng-model="newfriend.lastName" required />
<label>Address:</label><input type="text" data-ng-model="newfriend.address" required />
<label>Country:</label>
<select ng-model="newfriend.Country" ng-options="c.Name for c in countryList track by c.Id" ng-change="GetStatesList(newfriend.Country.Id)">
<option value="">Select Country</option>
</select>
<label>State:</label>
<select ng-model="newfriend.State" ng-options="s.Name for s in stateList track by s.Id">
<option value="">Select State</option>
</select>
<label>PostalCode:</label><input type="text" data-ng-model="newfriend.PostalCode" required />
<label>Notes:</label><input type="text" data-ng-model="newfriend.Notes" required />
<br />
<br />
<input type="submit" value="Add" data-ng-click="add()" data-ng-disabled="!addFriend.$valid" class="btn btn-primary" />
<input type="button" value="Cancel" data-ng-click="toggleAdd()" class="btn btn-primary" />
<br />
<br />
</form>
<table class="table table-bordered table-hover" style="width: 800px">
<tr>
<th>#</th>
<td>FirstName</td>
<th>LastName</th>
<th>Address</th>
<th>Country</th>
<th>State</th>
<th>PostalCode</th>
<th>Notes</th>
</tr>
<tr data-ng-repeat="friend in friends">
<td><strong>{{ friend.Id }}</strong></td>
<td>
<p data-ng-hide="friend.editMode">{{ friend.firstname}}</p>
<input data-ng-show="friend.editMode" type="text" data-ng-model="friend.firstname" />
</td>
<td>
<p data-ng-hide="friend.editMode">{{ friend.lastname }}</p>
<input data-ng-show="friend.editMode" type="text" data-ng-model="friend.lastname" />
</td>
<td>
<p data-ng-hide="friend.editMode">{{ friend.address }}</p>
<input data-ng-show="friend.editMode" type="text" data-ng-model="friend.address" />
</td>
<td>
<p data-ng-hide="friend.editMode">{{ friend.Country.Name }}</p>
<select data-ng-show="friend.editMode" ng-model="friend.Country" ng-options="c.Name for c in countryList track by c.Id" ng-change="$parent.GetStatesList(friend.Country.Id)">
<option value="">Select Country</option>
</select>
</td>
<td>
<p data-ng-hide="friend.editMode">{{friend.State.Name }}</p>
<select data-ng-show="friend.editMode" ng-model="friend.State" ng-options="s.Name for s in stateList track by s.Id">
<option value="">Select State</option>
</select>
</td>
<td>
<p data-ng-hide="friend.editMode">{{ friend.postalcode }}</p>
<input data-ng-show="friend.editMode" type="text" data-ng-model="friend.postalcode" />
</td>
<td>
<p data-ng-hide="friend.editMode">{{ friend.notes }}</p>
<input data-ng-show="friend.editMode" type="text" data-ng-model="friend.notes" />
</td>
<td>
<p data-ng-hide="friend.editMode"><a data-ng-click="toggleEdit(friend)" href="javascript:;">Edit</a> | <a data-ng-click="deletefriend(friend)" href="javascript:;">Delete</a></p>
<p data-ng-show="friend.editMode"><a data-ng-click="save(friend)" href="javascript:;">Save</a> | <a data-ng-click="toggleEdit(friend)" href="javascript:;">Cancel</a></p>
</td>
</tr>
</table>
<hr />
</div>
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bootstrap")
#Scripts.Render("~/bundles/angularjs")
<script src="~/Scripts/MyScript.js"></script>
</body>
I am trying to open my Country and state dropdown in edit mode and so far i am successfull in that.
But the only problem is when i am clicking on any record to open in edit mode my both country and state dropdown are binding correctly but when i am selecting other country from country dropdown then my ng-change is not firing and i dont know why.
This is my view for adding a new record:
<select ng-model="newfriend.Country" ng-options="c.Name for c in countryList track by c.Id" ng-change="GetStatesList()">
<option value="">Select Country</option>
</select>
<label>State:</label>
<select ng-model="newfriend.State" ng-options="s.Name for s in stateList track by s.Id">
<option value="">Select State</option>
</select>
My Controller:
function friendControllerTest($scope, $http) {
$scope.GetStatesList = function () {
//server side call to fetch state by country id
}
$scope.toggleEdit = function () {
this.friend.editMode = !this.friend.editMode;
getAllCountry();
if (this.friend.Country.Id > 0)
getStatebyCountryId(this.friend.Country.Id);
};
};
My Display records view:
<table class="table table-bordered table-hover" style="width: 800px">
<tr data-ng-repeat="friend in friends">
<td>
<p data-ng-hide="friend.editMode">{{ friend.Country.Name }}</p>
<select data-ng-show="friend.editMode" ng-model="friend.Country" ng-options="c.Name for c in countryList track by c.Id" ng-change="GetStatesList()">
<option value="">Select Country</option>
</select>
</td>
<td>
<p data-ng-hide="friend.editMode">{{friend.State.Name }}</p>
<select data-ng-show="friend.editMode" ng-model="friend.State" ng-options="s.Name for s in stateList track by s.Id">
<option value="">Select State</option>
</select>
</td>
</tr>
<table>
public class HomeController : Controller
{
//
// GET: /Home/
private FriendsEntities db = new FriendsEntities();
public ActionResult Index()
{
return View();
}
public ActionResult GetFriendsList(string text)
{
var data = db.Friends.Select
(
d => new FriendModel
{
Id=d.Id,
firstname = d.firstname,
lastname = d.lastname,
address = d.address,
notes = d.notes,
postalcode = d.postalcode,
Country = d.Country.Friends.Select
(
x => new CountryModel
{
Id=x.Country.Id,
Name = x.Country.Name
}
).FirstOrDefault(),
State = d.State.Friends.Select
(
s => new StateModel
{
Id=s.State.Id,
Name = s.State.Name
}
).FirstOrDefault()
}
).ToList();
return Json(data, JsonRequestBehavior.AllowGet);
}
[HttpPost]
public ActionResult AddFriends(Friends FriendsModel)
{
var result = db.Friends.Add(FriendsModel);
db.SaveChanges();
var data = db.Friends.Where(t => t.Id == result.Id).Select
(
d => new FriendModel
{
Id=d.Id,
firstname = d.firstname,
lastname = d.lastname,
address = d.address,
notes = d.notes,
postalcode = d.postalcode,
Country = d.Country.Friends.Select
(
x => new CountryModel
{
Id=x.Country.Id,
Name = x.Country.Name
}
).FirstOrDefault(),
State = d.State.Friends.Select
(
b => new StateModel
{
Id=b.State.Id,
Name = b.State.Name
}
).FirstOrDefault()
}
).SingleOrDefault();
return Json(data);
}
public ActionResult RemoveFriend(int id)
{
Friends friend = db.Friends.Find(id);
db.Friends.Remove(friend);
db.SaveChanges();
return Json(friend);
}
public JsonResult GetCountryState()
{
List<CountryModel> Country = new List<CountryModel>().ToList();
Country.Add(new CountryModel() { Id = 0, Name = "Select Country" });
var Data = db.Country.Select
(
d => new CountryModel
{
Id = d.Id,
Name = d.Name,
State = d.State.Select
(
x => new StateModel
{
Id = x.Id,
Name = x.Name
}
).ToList()
}
).ToList();
Country.AddRange(Data);
return Json(Country, JsonRequestBehavior.AllowGet);
}
public JsonResult GetCountry()
{
var Data = db.Country.Select
(
d => new CountryModel
{
Id = d.Id,
Name = d.Name,
}
).ToList();
return Json(Data, JsonRequestBehavior.AllowGet);
}
public JsonResult GetStateByCountryId(int CountryId)
{
var getStateList = db.State.Where(p => p.CountryId == CountryId).Select(x => new { x.Id, x.Name }).ToList();
return Json(getStateList, JsonRequestBehavior.AllowGet);
}
[HttpPut]
public ActionResult EditFriend(Friends FriendModel)
{
Friends friend = db.Friends.Find(FriendModel.Id);
friend.firstname = FriendModel.firstname;
friend.lastname = FriendModel.lastname;
friend.postalcode = FriendModel.postalcode;
friend.notes = FriendModel.notes;
friend.address = FriendModel.address;
friend.CountryId = FriendModel.Country.Id;
friend.StateId = FriendModel.State.Id;
db.SaveChanges();
var friendModel = new FriendModel();
friendModel.Id = friend.Id;
friendModel.firstname = friend.firstname;
friendModel.lastname = friend.lastname;
friendModel.postalcode = friend.postalcode;
friendModel.notes = friend.notes;
friendModel.address = friend.address;
friendModel.CountryId = friend.CountryId;
friendModel.StateId = friend.StateId;
return Json(friendModel);
}
}
public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
"~/Scripts/jquery-{version}.js"));
bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
"~/Scripts/jquery.validate*"));
// Use the development version of Modernizr to develop with and learn from. Then, when you're
// ready for production, use the build tool at http://modernizr.com to pick only the tests you need.
bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
"~/Scripts/modernizr-*"));
bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include(
"~/Scripts/bootstrap.js",
"~/Scripts/respond.js"));
bundles.Add(new StyleBundle("~/Content/css").Include(
"~/Content/bootstrap.css",
"~/Content/site.css"));
bundles.Add(new ScriptBundle("~/bundles/angularjs").Include(
"~/Scripts/angular.min.js"));
bundles.Add(new ScriptBundle("~/bundles/appjs").Include(
"~/Scripts/app/customerCtrl.js"));
}
}

Your problem is you are accessing scope inside ng-repeat & Directive like ng-repeat, ng-switch, ng-view, ng-include& ng-if does create a new scope from currently running scope. For referring parent scope method or variable you need use $parent, that provides access to parent
You should first need to read Understanding of Angular Scope Inheritance.
Plunkr for Explanation of the same.
Below is the only change required inside you markup
ng-change="GetStatesList()"
to
ng-change="$parent.GetStatesList()"
Hope this could help you, Thanks.

ng-change event not firing in Angularjs
You have two views .
1. Add record( give info to country ,state)
2. Display stored records (with edit mode to change country,state)
In your add record view ng-change="GetStatesList()" fires and show state list by calling GetStatesList() function friendControllerTest when country selected (model value changed) .
Your **Display records view has its own controller.it doesn't have GetStatesList() function ,so that ng-change not working .
Two solution for this issue is:
1. Make "$scope.GetStatesList()" to "$rootScope.GetStatesList()"- rootscope
2. Write service/factory method then you can use wherever you want.
EDIT:
but using $parent.GetStateList() is good practice as #pankajparkar's soltution

Related

I have a class emp with id name and list of technology type i want to fill it with data coming from dynamic textboxes

i want it to be solved in only angular-js.
<head>
#Scripts.Render("~/bundles/AddEmployee")
</head>
<body ng-app="TruModule">
<div ng-controller="trucontrolleraddemp">
<div style="margin-top:-20px;">
<h1 class="decor">Add Employee</h1>
<form name="emp" novalidate class="warn container" ng-mouseover="hidemessage()">
<div class="col-md-offset-2 row">
<div class="col-sm-4">
<table class="margin">
<tr>
<td>
<label for="id">Id*   :</label>
</td>
<td>
<span>{{id}}</span>
</td>
</tr>
<tr>
<td>
<label for="name">Name* :</label>
</td>
<td>
<input type="text" name="name" ng-model="employee.name" ng-required="true" ng-minlength="2" />
<span ng-show="emp.name.$touched && emp.name.$error.minlength">too short!!!</span>
</td>
</tr>
<tr>
<td>
<label for="role">Role  :</label>
</td>
<td>
<input type="text" name="role" ng-model="employee.role" ng-maxlength="3" />
<span ng-show="emp.role.$touched && emp.role.$error.maxlength">exceed!!!</span>
</td>
</tr>
<tr>
#* <td>
<label for="role">tech  :</label>
</td>
<td>
<input type="text" name="role" ng-model="technology.tech" ng-maxlength="6" />
<span ng-show="emp.role.$touched && emp.role.$error.maxlength">exceed!!!</span>
</td>*#
</tr>
</table>
</div>
<div class="col-sm-4">
<table id="tblEmployee">
<tr>
<td>
<label for="tech">Technologies* :</label>
</td>
<td>
<ul>
<li ng-repeat="techno in technology track by $index">
<input type="text" name="tech" ng-model="employee.technology[$index].tech" ng-required="true" ng-minlength="2" />
</li>
</ul>
</td>
<td>
<span><button class="img" ng-click="addtech()">+</button></span><br/><span><button class="img" ng-click="removetech()">-</button></span>
</td>
</tr>
</table>
</div>
</div>
</form>
<div class="mainloc">
<span><a class="img" href="#!Employee">&lt</a><button class="img position" ng-click="postdata(employee)" value="Submit">+</button> </span>
</div>
<span class="position" ng-hide="IsShown">
<img src="~/reload.gif" />
</span><span style="visibility:hidden"><img src="~/reload.gif" /></span>
<div class="dex alertpos" ng-hide="IsVisible">{{message}}</div>
</div>
<hr style="margin-top:91px;" />
</div>
</body>
i want data to be in the following format. it is the format
accepted by the model employee in controller in webapi.
{
"id":1,
"name":"erk",
"role": "sa",
"technologies":[
{"tech":"Test3"},
{"tech":"Test1"},
]
},
}
the format i am getting is like
this
{"id":4,
"name":"Sam",
"role":"sa",
"technology
":{"0":{"tech":"dfg"},
"1": {"tech":"dfgdfg"}},
}
I have tried using [$index] to make sure that each text box gets a
different value. But since it is returning objects with indexes, I do not
want like that. I want it to be replaced with tech.
/// <reference path="../scripts/angular-route.min.js" />
/// <reference path="../scripts/angular.min.js" />
/// <reference path="../scripts/angular-route.js" />
trumodule.service("idgenerator", function () {
this.idfunc = function () {
return Math.floor(((Math.random()) * 6) + 1);
}
});
var trucontrolleraddemp = function ($scope, $http, $timeout, $route, idgenerator) {
var id = idgenerator.idfunc();
$scope.id = id;
$scope.IsShown = true;
$scope.technology = [];
$scope.addtech = function () {
$scope.technology.push({});
}
$scope.removetech = function () {
$scope.technology.pop({});
}
$scope.postdata = function (data) {
if (data)
$scope.IsShown = false;
data.id = id
var employee = JSON.stringify(data);
$http({ method: "Post", url: '/api/values', data: employee, headers: { 'Content-Type': 'application/json' } })
.then(function (response) {
$scope.IsVisible = false;
$scope.message = response.data;
$timeout(function () {
$route.reload();
}, 2000);
});
}
$scope.message = "Please fill the fields to register a new Employee";
$scope.hidemessage = function () {
$scope.IsVisible = true;
}
$timeout(function () {
$scope.message = "Its mandatory to fill fields with *";
}, 2000);
}
trumodule.controller("trucontrolleraddemp", trucontrolleraddemp);
I have a class employee in that i have fields id, name, role and a list
technologies of type technology, which is another class containing string
field tech, I want data to be filled in that using ng-repeat.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace WebAPI_Angular.Models
{
public class Employee
{
public int id;
public string name;
public string role;
//public DateTime DoB;
public List<technology> technologies;
}
public class technology
{
public string tech;
}
}
I have found an alternative answer for my question but really want someone to tell me how can i bring the data at once and that too in the accepted format. Here i am posting my answer.
var trucontrolleraddemp = function ($scope, $http, $timeout, $route, idgenerator) {
var id = idgenerator.idfunc();
$scope.id = id;
$scope.IsShown = true;
$scope.technologies = [];
$scope.addtech = function () {
$scope.minus = true;
if ($scope.technologies.length<3)
$scope.technologies.push({});
}
$scope.removetech = function () {
$scope.technologies.pop({});
if (!$scope.technologies.length)
$scope.minus = false;
}
$scope.postdata = function (employee, technologies) {
if (employee)
$scope.IsShown = false;
employee.id = id
$scope.employee.technologies = [];
angular.forEach(technologies, function (value) {
$scope.employee.technologies.push(value);
});
var employee = JSON.stringify(employee);
$http({ method: "Post", url: '/api/values', data: employee, headers: { 'Content-Type': 'application/json' } })
.then(function (response) {
$scope.IsVisible = false;
$scope.message = response.data;
$timeout(function () {
$route.reload();
}, 2000);
});
}
$scope.message = "Please fill the fields to register a new Employee";
$scope.hidemessage = function () {
$scope.IsVisible = true;
}
$timeout(function () {
$scope.message = "Its mandatory to fill fields with *";
}, 2000);
}
trumodule.controller("trucontrolleraddemp", trucontrolleraddemp);
I am posting only changes that i have done in html.
<td>
<label for="tech">Technologies* :</label>
</td>
<td>
<ul>
<li ng-repeat="techno in technology track by $index">
<input type="text" name="tech" ng-model="employee.technology[$index].tech" ng-required="true" ng-minlength="2" />
</li>
</ul>
</td>
<td>
</td>
<td>
<span><span><button class="img2" ng-click="addtech()">+</button></span><span class="mar-l20"><button class="img2" ng-show=minus ng-click="removetech()">-</button></span></span>
</td>
</tr>
</table>

unable to repeat collections value using angularjs ng-repeat

I was trying to do a webAPI call from AnguarJs. I receive success response "data" object perfectly.When it is passed to HTML page under "ng-repeat" it is not displaying any records.
Following is the one not working
<tr ng-repeat = "cust in Customers">
<td>{{ cust.CustomerName }} </td>
<td>{{ cust.CustomerCode }}</td>
<td>{{ cust.CustomerAmount }}</td>
<td>{{ cust.ProcessDate }}</td>
</tr>
But if i put in this way it will display the 0th index records
<tr ng-repeat = "cust in Customers">
<td>{{cust[0].CustomerName }} </td>
<td>{{cust[0].CustomerCode }}</td>
<td>{{cust[0].CustomerAmount}}</td>
<td>{{cust[0].ProcessDate }}</td>
</tr>
Note : In the below code i split up files in different javascript files and referred in the main html page.Just for your information.
My Fiddle Link : JsFiddle
Please help me in resolve it.
function Utility(){
this.ApplicationVersion = "0.0.1";
this.ApplicationName = "AngularJs First Project";
this.getDate = function () {
var dt = new Date();
return dt.toDateString();
}
this.IsEmpty = function (value) {
if (value.length == 0) {
return false;
}
else {
return true;
}
}
}
function Customer(utility) {
this.CustomerCode = "1001";
this.CustomerName = "Ragu";
this.CustomerAmount = 100;
this.CalculateDiscount = function()
{
return 10;
}
this.ProcessDate = utility.getDate();
}
function Factory()
{
return {
CreateCustomer: function (utility) {
return new Customer(utility);
}
}
}
/// <reference path="Utility.js" />
/// <reference path="Customer.js" />
var myApp = angular.module("myApp", []);
myApp.controller("BindingCode",BindingCode);
myApp.factory("Factory", Factory);
myApp.service("UtilityObj", Utility);
function BindingCode($scope, UtilityObj, Factory,$http)
{
$scope.Customer = Factory.CreateCustomer(UtilityObj);
$scope.Customers = [];
$scope.Utility = UtilityObj;
$scope.Customer.CustomerCode = "1002";
$scope.Customer.CustomerName = "Raman";
$scope.Customer.ProcessDate = UtilityObj.getDate();
$scope.Color = "blue";
$scope.$watch("Customer.CustomerAmount", function () {
if ($scope.Customer.CustomerAmount < 1000) {
$scope.Color = "Red";
}
else {
$scope.Color = "Green";
}
});
$scope.Submit = function()
{
debugger
if ($scope.Utility.IsEmpty($scope.Customer.CustomerAmount)) {
debugger
$http.post("http://localhost:61860/api/Customer", $scope.Customer).then(function(data){
$scope.Customers = data;
debugger
$scope.Customer = {}; // clearing the record
},
function(data)
{
debugger
alert("inside error http call" + data);
}
);
//$http.post("http://localhost:61860/api/Customer", $scope.Customer).
// success(function (data) {
// debugger
// $scope.Customers = data;
// $scope.Customer = {};
//});
}
else {
alert("No Proper Date");
}
}
}
<script src="Scripts/angular.js"></script>
<script src="Customer.js"></script>
<script src="Utility.js"></script>
<script src="app.js"></script>
<body ng-app="myApp">
<div id="CustScreen" ng-controller="BindingCode">
CustomerCode : <input type="text" ng-model="Customer.CustomerCode" id="txtCustomercode" /> <br />
CustomerName : <input type="text" ng-model="Customer.CustomerName" id="txtCustomerName" /> <br />
CustomerDate : <input type="text" ng-model="Customer.ProcessDate" id="txtCustomerDate" /> <br />
CustomerAmount : <input type="text" style="background-color:{{ Color }}" ng-model="Customer.CustomerAmount" id="txtCustomerAmount" /><br />
<br />
{{ Customer.CustomerCode }} <br />
{{ Customer.CustomerName }} <br />
{{ Customer.ProcessDate }}<br />
{{ Customer.CustomerAmount}} <br />
<input type="submit" ng-click="Submit()" id="Submit" />
<table>
<tr>
<td>Name</td>
<td>Code</td>
<td>Amount</td>
<td>ProcessDate</td>
</tr>
<tr ng-repeat = "cust in Customers">
<td>{{cust.CustomerName }} </td>
<td>{{cust.CustomerCode }}</td>
<td>{{cust.CustomerAmount}}</td>
<td>{{cust.ProcessDate }}</td>
</tr>
</table>
</div>
</body>
Try this
$scope.Customers=data[0];

Ng-Controller Not Passing Data

I'm an angular newbie and am working on a small project and have come across a weird problem with ng-controller. When I use the controller within my partial view, the customer's name does not get passed into the value property.
However, if I inject the customersFactory (which has a function that makes an http request to the database to get all customers) into the ordersController, everything works fine.
My routeProvider code:
myApp.config(function($routeProvider) {
$routeProvider
.when('/', {
controller: 'ordersController',
templateUrl: 'partials/orders.html'
})
.when('/customers', {
controller: 'customersController',
templateUrl: 'partials/customers.html'
})
.otherwise({
redirectTo: '/'
})
});
myApp.factory('ordersFactory', function($http) {
var orders = [];
var factory = {};
factory.getOrders = function(callback) {
$http.get('/orders').success(function(data) {
orders = data;
callback(orders);
})
}
factory.addOrder = function(data) {
return $http.post('/add/order', data);
}
factory.deleteOrder = function(id) {
return $http.delete('/delete/order/' + id);
}
return factory;
});
myApp.factory('customersFactory', function($http) {
var customers = [];
var factory = {};
factory.getCustomers = function(callback) {
$http.get('/customers').success(function(data) {
customers = data;
callback(customers);
})
}
factory.addCustomer = function(data) {
return $http.post('/add/customer', data);
}
factory.removeCustomer = function(customer_id) {
return $http.delete('/delete/customer/' + customer_id);
}
return factory;
});
myApp.controller('ordersController', function($scope, ordersFactory) {
var getOrders = function() {
ordersFactory.getOrders(function(data) {
$scope.orders = data;
});
}
getOrders();
$scope.addOrder = function() {
console.log($scope.order);
ordersFactory.addOrder($scope.order);
$scope.order = {};
getOrders();
}
$scope.deleteOrder = function(id) {
ordersFactory.deleteOrder(id);
getOrders();
}
});
myApp.controller('customersController', function($scope, customersFactory) {
var getCustomers = function() {
customersFactory.getCustomers(function(data) {
$scope.customers = data;
})
}
getCustomers();
$scope.addCustomer = function() {
customersFactory.addCustomer($scope.customer);
$scope.customer = {};
getCustomers();
}
$scope.removeCustomer = function(customer_id) {
customersFactory.removeCustomer(customer_id);
getCustomers();
}
});
Here's the orders.html partial page.
<h2>Add New Order</h2>
<form>
<label for="name">Customer</label>
<select name="name" ng-model="order.name" ng-controller="customersController">
<option ng-repeat="customer in customers" value="{{customer.name}}">{{ customer.name }}</option>
</select>
<label for="quantity">Order</label>
<select name="quantity" ng-model="order.quantity">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
<select name="product" ng-model="order.product">
<option value="Nike Shoes">Nike Shoes</option>
<option value="Black Belts">Black Belts</option>
<option value="Ice Creams">Ice Creams</option>
<option value="Candies">Candies</option>
<option value="Waffles">Waffles</option>
</select>
<input type="submit" value="Order" ng-click="addOrder()">
</form>
<table>
<thead>
<tr>
<td>Customer Name</td>
<td>Product</td>
<td>Quantity</td>
<td>Date</td>
<td>Action</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="order in orders">
<td>{{ order.name }}</td>
<td>{{ order.product }}</td>
<td>{{ order.quantity }}</td>
<td>{{ order.date }}</td>
<td>Remove</td>
</tr>
</tbody>
</table>
Can anyone please explain why this is the case? My initial guess is that it has something to do with not explicitly assigning $scope.customers but I am under the impression that as soon as ng-controller is detected, it executes all of the "self-executing functions" which would then assign the data to $scope.customers. Thanks in advance.
Use ng-model in place of value and instead of <option> tag use ng-options in select tag it is fast as compare the <option> tag
<select name="name" ng-model="order.name" ng-controller="ordersController" ng-options="customer as customer in customers" />
Use the ngOptions directive instead. The documentation can be found here: https://docs.angularjs.org/api/ng/directive/ngOptions
<select name="name" ng-model="order.name" ng-options="customer as customer.name for customer in customers track by customer.name" ng-controller="ordersController">
Try ng-model="customer.name" instead of value="{{customer.name}}"
Thanks so much for your feedback. I think I've figured out the root of my issue(s).
I am not using ng-options to iterate over an array full of objects.
I am calling the ordersController in the routeProvider but am overriding it with customersController which is causing ng-model="order.name" to not be passed into the scope.
Any pointers on what I can do to fix #2? Does "ng-controller='customersController' have to come before the tag in order for "ng-options" to display the options correctly?

Bind data to table using ng-repeat on ng-change of dropdownlist

I want data to appear in table according to selected value. I want to bind data to table after data is fetched when ng-change of dropdownlist is triggered
<div ng-app="myapp" ng-controller="prodctrl" >
<select id="BrandDropdown" class="InstanceList" ng-change="GetBrandProd()" ng-model="Products">
<option>Select Brand</option>
#if (ViewBag.dataset != null)
{
foreach (string str in (string[])ViewBag.dataset)
{
<option value='#str.Split('/')[0]'>#str.Split('/')[1]</option>
}
}
</select>
<table ng-model="Products">
<tr ng-repeat="P in Products track by $index">
<td >{{x.Id}}</td>
<td >{{X.Rank}}</td>
<td >{{x.Name}}</td>
</tr>
</table>
</div>
this the code
var app = angular.module('myapp', []);
app.controller('prodctrl', function ($scope, $http) {
$scope.GetBrandProd = function () {
var Id = $('#BrandDropdown').val();
$http({
method: "GET",
url: "/Home/GetProdBrand",
params: {
id:Id
}
})
.success(function (response) {
$scope.Products = response.records;
});
}
})
I am able to get the data successfully in response.records. but after i get data nothing happens

Passing base64 string to object's attribute in AngularJS

I'm trying to upload an image via an input field, tie the base64 of the image to a variable, then add that variable to the attribute of an object so I can store it in my Firebase db.
Input form & field for object:
<div class="row modalDetail">
<h3>New Episode</h3>
<table class="">
<tbody>
<tr>
<td class="labelField">Name</td>
<td><input type='text' ng-model='episode.name'></td>
</tr>
<tr>
<td class="labelField">Title</td>
<td><input type='text' ng-model='episode.title'></td>
</tr>
<tr>
<td class="labelField">Description</td>
<td><input type='text' ng-model='episode.shortDescription'></td>
</tr>
<tr>
<td class="labelField">Time</td>
<td><input type='text' ng-model='episode.time'></td>
</tr>
</tbody>
</table>
<img src="../images/placeholder.png" id="pano">
<!-- START Image File Upload -->
<td class="labelField">Image</td>
<span class="btn btn-default btn-file">
<input type="file" accept="image/*" capture="camera" id="file-upload">
</span>
<div id="spin"></div>
<div class='btn btn-warning' ng-click='createEpisode()'> Create an Episode</div>
</div>
The service for uploading to Firebase:
'use strict';
app.service('Uploader', ['$firebase', 'FIREBASE_TEST_URL', function($firebase, FIREBASE_TEST_URL) {
var ref = new Firebase(FIREBASE_TEST_URL);
var episodes = $firebase(ref);
return {
all: episodes,
create: function(episode) {
location.reload();
//Add to firebase db
return episodes.$add(episode);
},
delete: function(episodeId) {
location.reload();
return episodes.$remove(episodeId);
},
update: function(episode) {
location.reload();
return episodes.$save(episode);
}
};
}]);
Controller that has the file handling for the image, etc.:
'use strict';
app.controller('UploadCtrl', ['$scope', 'Uploader', function ($scope, Uploader) {
$scope.episodes = Uploader.all;
$scope.createEpisode = function(){
Uploader.create($scope.episode).then(function(data){
$scope.episode.name = '';
$scope.episode.title = '';
$scope.episode.description = '';
$scope.episode.time = '';
$scope.episode.img1 = $scope.episodeImgData;
});
};
$scope.deleteEpisode = function(episodeId){
bootbox.confirm('Are you sure you want to delete this episode?', function(result) {
if (result === true) {
Uploader.delete(episodeId).then(function(data){
console.log('Episode successfully deleted!');
});
}
});
};
$scope.updateEpisode = function(episode) {
Uploader.update($scope.episode).then(function(data) {
console.log(episode);
console.log('Episode successfully updated.');
});
};
$scope.selectEpisode = function(object) {
$scope.selectedEpisode = object;
setTimeout(function(){ $scope.$apply($scope.selectedEpisode = object); });
};
// ********************************************************************************** //
// START Image Upload: https://github.com/firebase/firepano/blob/gh-pages/firepano.js //
// REQUIRED: app/scripts/js/crypto.js in index.js
var spinner = new Spinner({color: '#ddd'});
$scope.episodeImgData = '../images/defaultplaceholder.png';
function handleFileSelectAdd(evt) {
var f = evt.target.files[0];
var reader = new FileReader();
reader.onload = (function(theFile) {
return function(e) {
var filePayload = e.target.result;
var hash = CryptoJS.SHA256(Math.random() + CryptoJS.SHA256(filePayload));
$scope.episodeImgData = e.target.result;
document.getElementById('pano').src = $scope.episodeImgData;
console.log($scope.episodeImgData);
};
})(f);
reader.readAsDataURL(f);
}
function handleFileSelectEdit(evt) {
var f = evt.target.files[0];
var reader = new FileReader();
reader.onload = (function(theFile) {
return function(e) {
var filePayload = e.target.result;
var hash = CryptoJS.SHA256(Math.random() + CryptoJS.SHA256(filePayload));
$scpope.episodeImgData = e.target.result;
document.getElementById('pano2').src = $scope.episodeImgData;
$scope.selectedEpisode.img1 = $scope.episodeImgData;
console.log($scope.episodeImgData);
};
})(f);
reader.readAsDataURL(f);
}
$(function() {
$('#spin').append(spinner);
document.getElementById('file-upload').addEventListener('change', handleFileSelectAdd, false);
document.getElementById('file-upload2').addEventListener('change', handleFileSelectEdit, false);
});
// END Image Upload: https://github.com/firebase/firepano/blob/gh-pages/firepano.js //
// ******************************************************************************** //
}]);
All the attributes in the form save to the DB except img1. When the update button is clicked, I thought I could just pass in episodeImgData to the object (img1 variable) to save, but it doesn't save anything at all (just the form variables tied to episode.name, etc.). What's the best way to do this? I'm using parts of the FirePano example (https://github.com/firebase/firepano/blob/gh-pages/firepano.js) for the image handling.
Update (20160519): Firebase just released a new feature called Firebase Storage. This allows you to upload images and other non-JSON data to a dedicated storage service. We highly recommend that you use this for storing images, instead of storing them as base64 encoded data in the JSON database.
There were a lot of small problems with that code.
Since your episodes are an array, you can to create is with $asArray, otherwise it won't have a $add method: var episodes = $firebase(ref).$asArray();
You were calling location.reload() before sending the data to the server
Your file-upload handler wasn't triggering for me
There were dangling references to the spinner from firepano
I think that first two were the biggest. But it is hard to find that type of problem if you don't provide a minimal example that reproduces the problem. I did that for you now.
In the end, the code is not too big so I'll share it here:
var app = angular.module('myapp', ['firebase'])
.service('Uploader', function($firebase) {
var ref = new Firebase('http://<yourfirebase>.firebaseio.com/');
var episodes = $firebase(ref).$asArray();
return {
all: episodes,
create: function(episode) {
//Add to firebase db
return episodes.$add(episode);
}
};
})
.controller('UploadCtrl', function ($scope, Uploader) {
$scope.episodes = Uploader.all;
$scope.createEpisode = function() {
if ($scope.episodeImgData) {
$scope.episode.img1 = $scope.episodeImgData;
}
Uploader.create($scope.episode);
};
$scope.handleFileSelectAdd = function(evt) {
var f = evt.target.files[0];
var reader = new FileReader();
reader.onload = (function(theFile) {
return function(e) {
var filePayload = e.target.result;
$scope.episodeImgData = e.target.result;
document.getElementById('pano').src = $scope.episodeImgData;
};
})(f);
reader.readAsDataURL(f);
};
document.getElementById('file-upload').addEventListener('change', $scope.handleFileSelectAdd, false);
});
The corresponding (body) HTML:
<body ng-app='myapp'>
<div class="row modalDetail" ng-controller='UploadCtrl'>
<h3>New Episode</h3>
<table class="" ng-model='episode'>
<tbody>
<tr>
<td class="labelField">Name</td>
<td><input type='text' ng-model='episode.name'></td>
</tr>
<tr>
<td class="labelField">Title</td>
<td><input type='text' ng-model='episode.title'></td>
</tr>
<tr>
<td class="labelField">Description</td>
<td><input type='text' ng-model='episode.shortDescription'></td>
</tr>
<tr>
<td class="labelField">Time</td>
<td><input type='text' ng-model='episode.time'></td>
</tr>
</tbody>
</table>
<td class="labelField">Image</td>
<span class="btn btn-default btn-file">
<input type="file" accept="image/*" capture="camera" id="file-upload">
</span>
<div class='btn btn-warning' ng-click='createEpisode()'>Create an Episode</div>
<br/>
<img id="pano">
</div>
</body>
This is a working demo if creating an episode with optional image data: http://jsbin.com/roriwu/7.

Resources