How to pass data to angular async function from ng-click - javascript

I am trying to use an async function inside a service (so I can acces it from many controllers) and fill an array when I click on an element on the page.
As it is now, the async function will load right after page load. Here is the function ;
routesApp.factory('angRoutes', function($http) {
var angRoutes = {
async: function() { <----------- How to call this function with params
var data = $.param({
query: 'top' <------------------- HOW TO PASS SOMETHING HERE
}); <-- I need to use ng-click="update('top')"
var config = {
headers : {
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;'
}
}
var promise = $http.post('../ajax-php.php', data, config)
.success(function (data, status, headers, config) {
$('#ajaxLoader').hide(); /// hiding the loading gif
return data;
})
.error(function (data, status, header, config) {
return data = "Data: " + data +
"<hr />status: " + status +
"<hr />headers: " + header +
"<hr />config: " + config;
});
return promise;
}
};
return angRoutes;
});
And the controller ;
routesApp.controller('topRoutesCtrl', function topRoutesCtrl($scope,$http, angRoutes) {
angRoutes.async().then(function(data) {
$scope.angRoutes = data;
console.log(data);
});
});
I want to update my $scope.angRoutes using the same kind of async function but I need to pass data to the function. For Exemple ;
<div ng-controller="navRoutesCtrl" class="c prise">c
<img ng-click="update()" data-query="top" class= "priseimg" src="../images/prises/c-s.png">
<div class="arrow-all arrow-c">
TOP ROUTES
</div>
</div>
I use to do it with jquery and I would get the query param for the post from de data-query attribute.
Now I want to turn this into ;
<div ng-controller="navRoutesCtrl" class="c prise">
<img ng-click="update('top')" class= "priseimg" src="../images/prises/c-s.png">
<div class="arrow-all arrow-c">
TOP ROUTES
</div>
</div>
How do I change my service async function and set the .post query to what ever I pass to the update('query').
How do I need to rewrite the function so I can use it with ng-click
I want the exact same thing to happens but from a diffrent controller and a controller that will call the async function with a diffrent query.
Basically I need to call for an async $http function (result come from database and are sent as Json) from a ng-click with at least one param for the query.

Related

Access the session variables from controller inside ajax call

I have certain fields getting filled in my controller.
public string AjaxLogin()
{
//some code to check admin or not
Session["UserName"] = "Smith";
if(type="Admin")
{
Session["UserRole"] = 1;
}
Session["EmployeeID"] = 101;
}
I have an ajax call to this controller like below and if it is success, I need to access these session variables inside success to check the user role.
$.ajax(
{
url: GLOBAL.GetAppPath() + 'Home/AjaxLogin',
data: data,
type: 'POST',
error: function (xhr, status, error) {
console.log(error);
},
success: function (result, status, xhr) {
if (result == 'OK')
{
var UserVal = '#Session["UserRole"]';
alert(UserVal);
if(UserVal ==1)
{
var baseUrl ="#Url.Action("Admin","AdminPage")";
window.location.href = baseUrl;
}
else
{
var baseUrl ="#Url.Action("Admin","RegularPage")";
window.location.href = baseUrl;
}
}
else {
$('#msgError').html('Error: ' + result);
$('#msgError').css('display', 'block');
}
},
});
But I cannot access this variable in this call. I want to check the user role variable and give url actions accordingly.
If you want to redirect to a controller in your project you can use the Url helper for you
Sample:
return JavaScript( "window.location = '" + Url.Action("Edit","Dispatch") + "'" );
P.S: I couldn't comment since it asks for 50 reputation that's why I'm commenting it over here.

Angular use variable before running rest of the code

I know the problem is the order of execution, the scope fires async and loads the data after the rest of the code has been processed. I have a httpGET that gets the information from a web service and it's inside my Facebook share function when the user clicks the Facebook share button. But i tried adding a watch and .then with return promise in the httpget but both i could not get to work.
So the idea is the following: I have an CDImage that the user shares on facebook and i have another directory that holds promotional images for that same CD, not all of them so the httpGET checks if the promotionCDid exists if it exists the variable CDImage should be updated with the CDPromotionalURL instead of the standard url is get from CDImage so the user shares the Promotional image instead of the default CD cover.
So far the problem is that the CDImage does not change directly and console.log(CDImage) displays the CDCover the first time and when you click the button after several seconds the CDImage shows the CDPRomotionURL image.
var CDPromotionalImageUrl = "EMPTY";
$('#facebookshare').click(function () {
$scope.GetCDdata = function () {
$http({
method: 'Get',
url: "/GetCDPromotionImage?id_CD=" + promotionCDId,
})
.success(function (data, status, headers, config) {
$scope.CDdata = data;
CDPromotionalImage = $scope.CDdata[0].filename
$scope.CDPromotionalImageUrl = "https://website.com/" + CDPromotionalImage
})
.error(function (data, status, headers, config) {
$scope.message = 'Unexpected Error';
});
};
if (CDPromotionalImageUrl == "EMPTY") {
CDImage = CDImage;
} else {
CDImage = CDPromotionalImageUrl;
}
console.log(CDImage)
var $this = $(this);
var urlShare = (window.location.href);
var obj = {
method: 'share',
href: (urlShare),
picture: (CDImage),
title: 'The ' + CDName,
caption: "As heard on website.com",
description:(description)
};
function callback(response) {
//alert("Post ID: " + response['post_id']);
}
FB.ui(obj, callback);
});
$scope.GetCDdata();

update scope variable on submit and update view in angular js

I'm creating my first web app in angularjs and can't get the page to update with new values once the user submits text/numbers in an input box.
I'm using Java8, MongoDB, angularJS and twitter bootstrap
HTML:
<td>
<input type="text" class="form-control" placeholder="enter bugnumber" data-ng-model="auditdata.newbugnumber">
<h4>Bug Numbers</h4>
{{a}}
</td>
<td>
<button type="submit" data-ng-click="add(auditdata)" class="btn btn-danger" >Save</button>
</td>
In the HTML above i take input from user in ng-model=auditadata.newbugnumber but on server side it sill gets update in the bugnumber filed. The newbugnumber field is acting like a temp variable which is just used to send the new data to the server. The reason for using the temp variable is to avoid two way binding in angularjs.
I tried using $apply(), $watch and digest in the JS below but can't get the value to be updated in the view. The only way the data gets update in view is when i reload the page which is not an option
app.controller('listCtrl', function ($scope, $http,$route) {
$scope.isCollapsed = true;
$http.get('/api/v1/result').success(function (data) {
$scope.audit = data;
}).error(function (data, status) {
console.log('Error ' + data);
})
$scope.add= function(bugInfo) {
$http.post('/api/v1/result/updateBug', bugInfo).success(function (data) {
bugInfo.newbugnumber='';
console.log('audit data updated');
}).error(function (data, status) {
console.log('Error ' + data);
}
};
});
Update function on server side
public void updateAuditData(String body) {
Result updateAudit = new Gson().fromJson(body, Result.class);
audit.update(
new BasicDBObject("_id", new ObjectId(updateAudit.getId())),
new BasicDBObject("$push", new BasicDBObject().append("bugnumber",
updateAudit.getNewbugnumber())));
}
how bugnumber filed in collection looks like
> db.audit.find({"_id" : ObjectId("5696e2cee4b05e970b5a0a68")})
{
"bugnumber" : [
"789000",
"1212"
]
}
Based on your comment, do the following:
Place all your $http handling i a service or factory. This is good practice and makes reuse and testing easier
app.factory('AuditService', function($http) {
var get = function() {
return $http.get("/api/...") // returns a promise
};
var add = function() {
return $http.post("/api/...") // returns a promise
};
return {
get: get,
add: add
}
});
And then in your controller
// note the import of AuditService
app.controller('listCtrl', function ($scope, $http,$route, AuditService) {
// other code here
// If insert is successful, then update $scope by calling the newly updated collection.
// (this is chaining the events using then())
$scope.add = function(bugInfo) {
AuditService.add().then(
function(){ // successcallback
AuditService.get().then(
function(data){ // success
$scope.audit = data;
},
function(){ // error
console.log('error reading data ' + error)
})
},
function(error){ // errorcallback
console.log('error inserting data ' + error)
})
});
The same approach can be applied to all CRUD operations

ajax postback method for refreshing dropdown list

Scoop...
I have a drop down list that might not display a particular option you're looking for. I added a button with pop up modal to type in a field you want to add to the drop down list. It functions perfectly, but I need to add an ajax postback method to refresh the list after the user hits enter. I don't want to refresh the whole page, just the list. any help?
Controller:
public ActionResult AddLeadSource()
{
return View();
}
[HttpPost]
public ActionResult AddLeadSource(string name)
{
LeadSource ls = new LeadSource();
ls.Name = name;
db.LeadSources.Add(ls);
db.SaveChanges();
return Json(new { success = true });
}
JS
<script>
$("#AddNew").change(function () {
var name = $("#Name").val();
// var order = $("#DisplayOrder").val();
$.ajax({
type: 'POST',
dataType: 'json',
cache: false,
url: '/Admin/LeadSource/AddLeadSource',
data: { name: name },
success: function (response) {
//alert("Success " + response.success);
$('#FollowUpNotes').kendoWindow('destroy');
// Refresh the DropDown <-- Heres where I need some help!
},
error: function (jqXHR, textStatus, errorThrown) {
alert('Error - ' + errorThrown);
}
});
});
In your success function of your Ajax call add this:
$("IdOfDropDownList").data("kendoDropDownList").dataSource.read();
In this way your dropdownlist will call the read function and reload all data. I assumed that your dropdownlist is binding throught read call.
I highly recommend looking at jQuery UI's autocomplete widget. That said,
$('#YourDropDownID option').remove(); //this will remove all option elements inside the <select id="YourDropDownID">
Then you just need to build new ones based on the response data,
for (var o in data) {
if (data[o].Value != undefined) {
$('#YourDropDownID').append('<option value="' + data[o].Value + '">' + ("" + data[o].Display) + '</option>');
}
}
I do this inside the .done() callback of my AJAX:
.done(function (data) {
//above code
}
Depending on the nature of the data you are sending back you may need to loop through it differently. Mine is an array of objects with a Value and Display properties (in my case, account numbers and account names).
//server side controller
var query = #"
Select
SubString([mn_no], 0, 6) As Value,
RTRIM([acct_desc]) As Display
From [some_table]";
return con.Query(query, new { AccountNumber = accounts.Select(x =>
{
return new { Value = x.Value, Display = x.Display };
});

ng-repeat update after build

I have a list of events that gets build from a JSON call to my server. The list gets parsed through ng-repeat. I want to implement a like button for the event and if its liked, replace that with unlike.
<a ng-show='event.liked==null' ng-click="like(event.event_id)">Like</a>
<a ng-show='event.liked!=null' ng-click="unLike(event.event_id)">Unlike</a>
Everything works perfectly except I have to refresh the feed to show "Unlike". Is there a way I can update the specific list item at the index that was liked once clicked without the need to refresh.
Please let me know if you need more information. Thanks!
edit: adding like function & unlike function. All it does is send request to my server to like or unlike a specific event with the event_id and user token.
$scope.like = function (event_id) {
var url = www.server.com?type=unlike&event_id=...
$http.post(url).success(function (data) {
console.log('success like');
//I want it to update my index here
}).error(function (data) {
console.log('fail like');
});
};
$scope.unLike = function (event_id) {
var url = www.server.com?type=unlike&event_id=...
$http.post(url).success(function (data) {
console.log('success unlike');
//I want it to update my index here
}).error(function (data) {
console.log('fail unlike');
});
};
Instead of passing in the event_id, pass the object to the like and unLike functions and update the object in success handler.
HTML
<a ng-hide='event.liked' ng-click="like(event)">Like</a>
<a ng-show='event.liked' ng-click="unLike(event)">Unlike</a>
Controller
$scope.like = function(event) {
var url = 'www.server.com?type=unlike&event_id=' + event.event_id;
$http.post(url).success(function (data) {
event.liked = true;
console.log('success like');
}).error(function (data) {
console.log('fail like');
});
};
$scope.unLike = function(event) {
var url = 'www.server.com?type=unlike&event_id=' + event.event_id;
$http.post(url).success(function (data) {
event.liked = null;
console.log('success unlike');
}).error(function (data) {
console.log('fail unlike');
});
};

Categories

Resources