I am new to angular-js and building a simple to-do application. I am creating a task and displaying the created task in a html table using ng-repeat. But the problem is that after posting the data, $scope.tasks variable is updated on controller side, but not in view. The view updates after refreshing the web page only and the task is added to html table. How can I make the view update after creating the task. Thanks in advance. Here is my code:
In my controller:
var app = angular.module('MyApp', ['ngMaterial', 'ngMessages']);
app.controller('DemoCtrl', function($scope,$mdSidenav,$mdDialog,$interval,$http,$mdToast) {
$scope.tasks = [];
_refreshTaskData(); //initial refresh
$scope.submitForm = function() {
var description = "";
var taskId = "";
$scope.formData = {
taskId: $scope.taskId,
description: $scope.description,
};
$http({
method: "POST",
url: 'savetask',
data: angular.toJson($scope.formData),
headers : {
'Content-Type': 'application/json',
}
}).then(_success, _error);
};
function _refreshTaskData() {
$http({
method : 'GET',
url : 'getTask',
}).then(function(res) { // success
$scope.tasks = res.data;
}, function(res) { // error
console.log("Error: " + res.status + " : " + res.data);
});
}
function _success(res) {
$mdDialog.hide();
console.log('in success function');
_refreshTaskData(); ;
}
function _error(res) {
//error handling
}
});
In my view:
<table>
<tr ng-repeat=" t in tasks">
<td>{{t.id}}</td>
<td>{{t.description}}</td>
</tr>
</table>
You must understand that these JS frameworks are asynchronous. Now what happens is, if you do an API call and make another API call whose result is based on the first one, the console does not wait for the result from one API and directly moves forward. SO what's happening in your case is sometimes/many times, before the POST call is served, the controller is not able to get fresh data with GET in time, thus not updating the view. What you can possibly do is enforce the GET only when POST is served
$http({
method: "POST",
url: 'savetask',
data: angular.toJson($scope.formData),
headers : {
'Content-Type': 'application/json',
}
}).then(function(res){
$http({
method : 'GET',
url : 'getTask',
}).then(function(res) { // success
$scope.tasks = res.data;
}, function(err) { // error
console.log("Error: " + err.status + " : " + err.data);
});
});
It would be best if you are sending a success message from the backend and checking before GET call
I think you are not calling _refreshEmployeeData at any point of time. If you add that instead of _refreshTaskData in your JS, then you will be able to see the result in view.
Also kindly use ng-init to call the _refreshEmployeeData in the controller. That would be the best way to initialize the fields.
var post1 = $http({
method: "POST",
url: "/Home/GetunAvailableDates",
dataType: 'json',
data: sub1,
headers: { "Content-Type": "application/json" }
});
var a = [];
post.then(function (d) {
if (d) {
for (var i = 0; i < d.data.length; i++) {
a.push(d.data[i].valueOf(Text).Text)
}
}
console.log("success");
}, function (d) {
$window.alert("Oops!! Something went wrong!!!!.");
});
this.selectedDates = a;
I'm currently working in mvc project.
I'm using AngularJs datepicker for my booking page. I need to disable dates which booking is unavailable.
I retrieve dates from database as list inside my booking.js file
My problem is how can bind that list of dates to angular datepicker. I tried so many ways but result was not good. guys help me how can i do that using angular.
I have an application made with .NET core framework and pure html in the front end. I was using AJAX to post and get data.
I am new to Angular and decided to convert the front end of the application to Angular for learning purposes.
For Example, I have a button that will change the state of employees from 'Billed' to 'Available' state. The ID for available state is defined in the back end and it is '1'.
//MOVE TO BENCH BUTTON CLICK
$(document).ready(function()
{
var allVals = [];
$("#MoveToBench").click(function()
{
$('input:checkbox:checked').each(function () {
allVals.push($(this).val());
});
for (i = 0;i<allVals.length;i++){
PostBenchList(allVals[i])
}
function PostBenchList(entityId) {
var data = 'entityID='.concat(entityId).concat('&nextStateId=1');
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "http://localhost:1783/api/Workflow?"+data,
data: data,
dataType: "text",
success: function (data) {
location.reload();
alert("Successfully added the selected Employees to TalentPool");
},
fail: function (error) {
Console.Log(error);
}
})
}
});
});
The above code is taking an array of entityID's as input. For the Angular application, the array is not required as only one entity ID will be passed.
The API controller in the backend is :
// POST api/values
[HttpPost]
public void Post(int entityId, int nextStateId)
{
JObject jsonObject = JObject.Parse(System.IO.File.ReadAllText("Config.Json"));
string jsonFile = jsonObject.GetValue("WorkfowJsonFileLocation").ToString();
var nextState = _stateServices.Get(nextStateId);
var handler = new WorkflowHandler(nextState, jsonFile, _entityServices, 1, _stateServices, _subStateServices, _appServices);
handler.PerformAction(entityId);
}
The above code worked for me and it would change the state ID of the employee(EntityID)to 1(nextStateId)
Now I have a button in AngularJS and I want it to do the same action. How would I achieve this? As I am still in the procedure of learning, I don't have a clue how to do this. Can anyone help me to achieve this? This would help me to learn and do all similar buttons.
Thank You.
You can use ng-click and call a function to post the data,
HTML:
<button ng-click="PostData()">
Click to POST
</button>
Controller:
app.controller('PostController',['$scope',function($scope)
{
$scope.sendPost = function() {
var data = $.param({
json: JSON.stringify({
name: $scope.newName
})
});
$http.post("/echo/json/", data).success(function(data, status) {
$scope.hello = data;
})
}
}]);
DEMO APP
I'm currently developing an AngularJS form which on submit pushes single or multiple participant data to an SQL database.
I'm able to push data to the SQL database, but I'm wanting to trigger a callback that redirects the user once all participant data has been successfully submitted.
At the moment on success it redirects the user but, misses the next foreach submit for the next participant.
Any and all advice would be appreciated.
AngularJS
/* Submit */
$scope.submit = function() {
var array = $scope.form.participants;
//console.log(array);
angular.forEach(array, function(value, key){
var request = $http({
method: "post",
url: 'http://xxx.co.uk/submit.php',
data: {
coachName: $scope.form.program.coachName,
contactArea: $scope.form.program.contractArea,
postcode: $scope.form.program.postcode,
programmeStart: $scope.form.program.programmeDate,
sessionDate: $scope.form.program.sessionDate,
sessionNumber: $scope.form.program.sessionNumber,
weekNumber: $scope.form.program.weekNumber,
id: value.participant.id,
attendance: value.participant.attendance,
weight: value.participant.weight,
goldBehaviours: value.participant.goldBehaviours,
stepCount: value.participant.stepCount,
creditData: value.participant.creditData,
weekOne: value.participant.weekOne,
stepOne: value.participant.stepOne,
weekTwo: value.participant.weekTwo,
stepTwo: value.participant.stepTwo,
weekThree: value.participant.weekThree,
stepThree: value.participant.stepThree,
weekFour: value.participant.weekFour,
stepFour: value.participant.stepFour,
weekFive: value.participant.weekFive,
stepFive: value.participant.stepFive
},
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}).success(function(data) {
//console.log(data);
$location.path("/thankyou");
});
});
};
Data
{
"program":{
"coachName":"AD",
"contractArea":"Berkshire",
"postcode":"NN1",
"programmeDate":"2016-08-15T23:00:00.000Z",
"sessionDate":"2016-08-16T23:00:00.000Z",
"sessionNumber":"1",
"weekNumber":"2"
},"participants":[
{"participant":{"id":"AW01","attendance":"Did Not Attend","weight":"1","goldBehaviours":"2","stepCount":"3","creditData":"","weekOne":"4","stepOne":"4","weekTwo":"5","stepTwo":"5","weekThree":"6","stepThree":"6","weekFour":"7","stepFour":"7","weekFive":"8","stepFive":"8"}},
{"participant":{"id":"AW02","attendance":"Attended","weight":"2","goldBehaviours":"3","stepCount":"4","creditData":"","weekOne":"5","stepOne":"5","weekTwo":"6","stepTwo":"6","weekThree":"7","stepThree":"7","weekFour":"8","stepFour":"8","weekFive":"9","stepFive":"9"}}
]
}
You can inject $q to your controller/service and use $q.all method (you can also use native Javascript Promise if you're not worried about old browsers support).
The all method takes an array of promises and resolve when all promises in the array resolve (it will reject if any of the promises reject).
$scope.submit = function() {
var array = $scope.form.participants;
var promises = [];
//console.log(array);
angular.forEach(array, function(value, key){
promises.push($http({
method: "post",
url: 'http://xxx.co.uk/submit.php',
data: {
coachName: $scope.form.program.coachName,
...
...
...
stepFive: value.participant.stepFive
},
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}));
});
$q.all(promises).then(function() {
$location.path("/thankyou");
});
};
You are telling it to redirect with each iteration, not after all iterations have been completed. Try moving your redirect like so:
angular.forEach(array, function(value, key){
var request = $http({
method: "post",
url: 'http://xxx.co.uk/submit.php',
data: {
coachName: $scope.form.program.coachName,
contactArea: $scope.form.program.contractArea,
postcode: $scope.form.program.postcode,
programmeStart: $scope.form.program.programmeDate,
sessionDate: $scope.form.program.sessionDate,
sessionNumber: $scope.form.program.sessionNumber,
weekNumber: $scope.form.program.weekNumber,
id: value.participant.id,
attendance: value.participant.attendance,
weight: value.participant.weight,
goldBehaviours: value.participant.goldBehaviours,
stepCount: value.participant.stepCount,
creditData: value.participant.creditData,
weekOne: value.participant.weekOne,
stepOne: value.participant.stepOne,
weekTwo: value.participant.weekTwo,
stepTwo: value.participant.stepTwo,
weekThree: value.participant.weekThree,
stepThree: value.participant.stepThree,
weekFour: value.participant.weekFour,
stepFour: value.participant.stepFour,
weekFive: value.participant.weekFive,
stepFive: value.participant.stepFive
},
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}).success(function(data) {
//console.log(data);
});
$location.path("/thankyou");
});
Your redirect needs to be outside of your forEach.
I am curious if there is a way to get Angular Grid to listen of a "deselect" devent, similar to it's "rowSelected" event.
I have a table where one column is a checkbox. I would like that table to send a POST indicating whether a checkbox has been selected or deselected (the server will want to know which one it was).
I was able to get the table to send a message when the checkbox is selected using:
$scope.gridOptions = {
rowSelected: myRowSelectFunc,
rowDeselected: myRowDeselectedFunc // Is there a listener for this?
}
function myRowSelectFunc(row) {
$http({method: 'POST',
url: 'api/submit',
params: { selected: true,
userid: row.userid}});
}
function myRowDeselectFunc(row) {
$http({method: 'POST',
url: 'api/submit',
params: { selected: true,
userid: row.userid}});
}
However, I am not sure how to do the same on a row deselect.
Thanks!
There is no event listener for deselecting a row. Though you can perform your logic in the selected event using a flag
$scope.gridOptions = {
rowSelected: myRowSelectFunc($event)
}
function myRowDeselectFunc(event) {
if(event.node.isSelected()) {
// your deselection logic
}
else {
$http({method: 'POST',
url: 'api/submit',
params: { selected: true,
userid: row.userid}});
}
}
Hope it helps !