Angular use variable before running rest of the code - javascript

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();

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.

Painfully slow ajax calls using jQuery

I'm using knockout in my application to register/login from a form but the wait times on ajax calls are painfully slow first time 'round (guessing it's caching afterwards as it's really quick second time 'round) - around fifteen seconds to login when I upload the site online, and when I wrap it up as an iOS app (HTML5 application) it takes over SIXTY seconds to complete login. Why could this be happening? Have I missed something? Is it more likely to be server-side? Hopefully I can give enough info but unfortunately I'm new to this. I'll add the Login code below:
$(document).ready(function(){
function UserViewModel() {
//Make the self as 'this' reference
var self = this;
var Domain = "http://example.com";
//Declare User observables which will be bind with UI
self.UserId = ko.observable();
self.Name = ko.observable();
self.Email = ko.observable();
self.Occupation = ko.observable();
self.Country = ko.observable();
self.RegistrationNumber = ko.observable();
//Create User object
var User = {
UserId: self.UserId,
Name: self.Name,
Email: self.Email,
Occupation: self.Occupation,
Country: self.Country,
RegistrationNumber: self.RegistrationNumber,
};
//Assign knockout observables to User/s objects
self.User = ko.observable(); //user
self.Users = ko.observableArray(); // list of users
//onload set status of user
UserStatus();
//Login handler
self.login = function () {
try {
if (User.Email() != "" && User.RegistrationNumber() != "") {
//try logging in
Login();
} else {
viewModel.UserId("Please login with the correct email and registration number.");
}
}
catch (err) {
viewModel.UserId("There was an error, please try again.");
}
};
//Login
function Login() {
$.ajax({
url: Domain + '/User/Login',
cache: false,
type: 'POST',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
data: '{"Email":"' + User.Email() + '","RegistrationNumber":"' + User.RegistrationNumber() + '"}',
beforeSend: function () {
// setting a timeout
$('.splash').show();
},
success: function (data) {
$('.splash').hide();
if (data != 0) {
SetUserVars(data.UserId, data.Name, data.Email, data.Occupation, data.Country, data.RegistrationNumber);
viewModel.UserId(ActionToTake());
}
else {
viewModel.UserId("The supplied credentials are invalid, please try again.");
}
},
complete: function () {
//$('.splash').hide();
},
}).fail(
function (xhr, textStatus, err) {
console.log(xhr.statusText);
console.log(textStatus);
console.log(err);
viewModel.UserId("There was an error, please try again.");
});
}
function UserStatus() {
if (localStorage.getItem("UserId") === null) {
//not logged in
$("a.menu-status").text("Login").attr("href", "index.html#login-screen");
}
if (localStorage.getItem("UserId") != null) {
//logged in
$("a.menu-status").text("Logout").attr("href", "index.html#login-screen");
}
//allow user to logout and reset all user storage
$("a.menu-status").click(function () {
//show logged off status
$("a.menu-status").text("Login");
alert('You have logged off, please login if you wish to continue.');
self.reset();
//redirect
window.location.replace("index.html#login-screen");
location.reload();
viewModel.UserId("You have logged off.");
ResetUserLocalStorage();
});
}
Id be inclined to agree with the comments that the issue lies with the server side and not the client side.
The steps id take initially would be to use something like postman https://www.getpostman.com/ and hit the API through that, verify that its the slow part.
If that shows the issue then can you get yourself in a debug situation with the code thats running on the server? Then step through the code and try to pin point exactly whats happening and where its slowing down.

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 };
});

How to avoid data mix between $scope variables in ng-repeat when it is broadcasted in other controller?

I have two controllers. In one controller I am storing the data in scope variable for different categories and for different weeks and days. Here is the function for the same:
$scope.fetchWeekList = function(type) {
$scope.loading = true;
var paramtype = (type == 'mo')?'Mobiles':((type == 'ta')?'Tablets':((type == 'la')?'Laptops':'TVs'));
var weekListUrl = url + "/" + paramtype;
var request = $http({
method: "GET",
url: weekListUrl,
headers: { 'Accept' :'application/json','Content-Type' :'application/json', 'Accept-Language': 'en'}
});
request.success(
function(data) {
$scope.weekList = data.object;
$scope.loading = false;
});
request.error(
function(data, status) {
console.log(status);
$scope.weekList = data || "Request failed";
$scope.loading = false;
});
};
Please pat attention that I am fetching the data for the week lists for all the categories with this single function.
Then I am using this:
$scope.$on('fetchSaleDetails', function(event,type) {
$scope.fetchWeekList(type);
}
Then I am broadcasting it in the other controller like this:
$rootScope.$broadcast('fecthSaleDetails','mo');
$rootScope.$broadcast('fecthSaleDetails','ta');
$rootScope.$broadcast('fecthSaleDetails','la');
But when I switch the company the weeks of one category appears in the other and when I click again on the company the data changes. This is the function to update company.
$scope.updateCom = function(corresCom) {
$("html, body").animate({scrollTop: 0 }, "slow");
$rootScope.$broadcast('updateComDetail',corresCom);
$rootScope.$emit('fetchSaleDetails','mo');
$rootScope.$broadcast('fecthSaleDetails','mo');
$rootScope.$broadcast('fecthSaleDetails','ta');
$rootScope.$broadcast('fecthSaleDetails','la');
$scope.selectedCom = corresCom;
};
I would be grateful if someone can tell me the issue here. I have tried my best but no luck.
Thanks.

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