Angularjs:Empty object, when have only one click? - javascript

This function i call on ng-click.
HTML
<div class="col-md-offset-10">
<div class="form-group">
<a class="btn btn-default" ng-click="schedule ()">Add</a>
</div>
</div>
JS
$scope.scheduleid={};
var inc=0;
$scope.schedule = function ()
{
inc += 1;
console.log($scope.from);
console.log ($scope.dateObj);
if (inc == 1)
{
var schedule = {}
schedule._type = "Schedule";
console.log($scope.dateObj);
var insertSchedule = BasicJSONCreator.basicEdit ();
insertSchedule.Calls[0].Arguments = [];
insertSchedule.Calls[0].Arguments[0] = schedule;
httpRequester.async (insertSchedule).then (function (data) {
console.log(data.data.ReturnValues[0].scheduleID);
$scope.scheduleid=data.data.ReturnValues[0] //This get response from my database
console.log($scope.scheduleid ); // here object is get my data from database
});
}
$scope.getData();
}
This funciton i want get result from $scope.scheduleid, but here is problem.
When i have one click $scope.scheduleid (empty), but two and more click $scope.scheduleid (no empty and get data).Why my first click is Empty.
$scope.getData=function()
{
console.log($scope.scheduleid)
// Here my object is empty when have one click,but two and more click object no empty and get data
}

You are making an HTTP request, I think the problem is there. When you first call your function through the click, your call is being processed, and your function keeps going on.
That's why when you click once, at the end of your function, your object is empty. Once your object is loaded -let's say, at your second click-, you will finally receive it. What you should do is wait for your HTTP call to end before processing. You can do this the dirty way ($timeout) or looking at solutions like this one which should provide useful informations.

Related

Getting JSON data available to all scopes in JQuery/ javascript

With JQuery, I'm loading a set of postcode data via a json call, which is loaded once on document load to populate an option select. I can do that within the one function and it's fine.
However, every time the user selects a different postcode in the select, the code is fired (via .change), and I'm required to load the (quite large) same json data again to populate some different fields.
Because the first call is contained in the callback function, the data never gets outside that scope, and can't be reused again.
If someone changes the items 100 times, that's 100 times the data gets loaded, which seems wasteful, and slow.
Is there any way to call that data once, and have it available to the global/wider scope so it's accessible to the .change function?
EDIT Here's the code:
$(document).ready(function() {
GetPostcodes();
$("#postcodes").change(function() {
console.log("Selection Changed to " + $(this).val());
});
});
function GetPostcodes() {
$.getJSON("population.json", function(cases) {
var filtercases = $(cases).filter(function(i, n) {
return n.POA_NAME16 >= "2450" && n.POA_NAME16 <= "2489"
});
var postcodes = [];
$.each(filtercases, function(i, n) {
postcodes.push(n);
});
postcodes = postcodes.unique();
postcodes = postcodes.sort();
var options = [];
for (var i = 0; i < postcodes.length; i++) {
options.push('<option value="',
postcodes[i].POA_NAME16, '">',
postcodes[i].POA_NAME16, '</option>');
}
$("#postcodes").html(options.join(''));
});
}
Here's what the JSON looks like:
{
"POA_NAME16": 2000,
"Combined": "BARANGAROO,DARLING HARBOUR,,DAWES POINT,HAYMARKET,MILLERS POINT,PARLIAMENT HOUSE,SYDNEY,SYDNEY SOUTH,THE ROCKS",
"Tot_p_p": 27411
},
{
"POA_NAME16": 2006,
"Combined": "THE UNIVERSITY OF SYDNEY",
"Tot_p_p": 1259
},
So while I'm only using the postcode data in the first call to populate the drop down box, I'd like to be able to access all the information for when the .change property is fired to show the other information.
Cheers
I think the problem has come that I've tried to do this:
GetPostcodes();
console.log(the global variable I set)
which doesn't work.
But if I don't reference that global variable until another event, everything's in there and working - so although I already had the answer - your help pushed me to look further in. Cheers :P

AngularJS - Handling dynamic search using $http and debounce

I have a text input below, bound to a model req.mod1, with a debounce delay in updating model, that calls a pullData() function.
<input type="text" class="form-control" ng-change="pullData()" ng-model-options="{debounce: 1000}" ng-model="req.mod1">
Inside of pullData() I have a simple $http.get request, that pulls data and updates some other fields in the form.
$scope.pullData = function(){
var pullingData = true;
if (!pullingData){
$http.get('example.com/search/' + $scope.req.mod1 ).then(res)
...
$scope.req.mod2 = res.data.mod2;
$scope.req.mod3 = res.data.mod3;
var pullingData = false;
...
}
}
The problem that arises is that multiple calls stack on top of each other -- I think -- and so if a user happens to input text, wait >1second, and type some more, the call would go out with the first inputted text. Then it would pull the data and update the form with the first res. I'm trying to keep track of the request with a pullingData var.
Any ideas on how to handle a truly dynamic search call? Is there a way to cancel requests if a new one comes in? Or maybe just tell angular to constantly overwrite it?
Thanks in advance.
I think this is what you need
http://odetocode.com/blogs/scott/archive/2014/04/24/canceling-http-requests-in-angularjs.aspx
When you create a request.. it's called Promise, so what you need to cancel is that.
Something like this:
app.factory("movies", function($http, $q){
var getById = function(id){
var canceller = $q.defer();
var cancel = function(reason){
canceller.resolve(reason);
};
var promise = $http.get("/api/movies/slow/" + id, { timeout: canceller.promise})
.then(function(response){
return response.data;
});
return {
promise: promise,
cancel: cancel
};
};
return {
getById: getById
};
});
When the user enters something to search, your app should always search by the user's input. It means that you shouldn't cancel the user's input.
For example, the user want to search something about 'starwar', when he/she enter 'star', and you get some result. If now you cancel the 'war' which is entered after, the result is not good. So just let Angular override the result.
Moreover, some errors in your example of code, when you call pullData, it never passes the if check:
$scope.pullData = function(){
var pullingData = true;
// !pullingData is always false
if (!pullingData){
$http.get('example.com/search/' + $scope.req.mod1 ).then(res)
}
}

Cant get the current id of a data from local Storage using jquery

I am working on an app to store data offline. My problem is when I try to retrieve the data from local storage for update/edit, it keeps calling only the id of the first item, and not calling the id of the data in view.
Please what am I doing wrong?
Here is my code for loading employees:
// load cases from localStorage
var employees;
if (localStorage.getItem('employees')) {
employees = JSON.parse(localStorage.getItem('employees'));
} else {
// If no cases, create and save them
employees = [];
// offling storing of our cases
localStorage.setItem('employees', JSON.stringify(employees));
}
// show case listing in list view page
var showEmployees = function () {
//erase existing content
$('#employee_list').html('');
//insert each employee
for (var i = 0; i<employees.length; i++) {
addEmployees(employees[i]);
}
};
Here is my code to add an employee to list view:
//add an eliment to list view
var addEmployees = function (empData) {
//HTML content of one list element
var listElementHTML = '<li><a class="employee_list" ui-btn ui-btn-e ui-btn-icon-right ui-icon-carat-r" data-transition="fade" data-split-icon="delete" href="#item'+empData.id+'">' + empData.employeename + '<br> ' + empData.dateofbirth + '</br></a></li>';
//appending the HTML code to list view
$('#employee_list').append(listElementHTML);
};
Here is my code for Edit function:
//User input to edit form
$('#edit_employee_page').on('click' , function () {
var editEmployee = JSON.stringify({
id: employees.length+1,
employeeno: $('#employeeno').val(),
employeename:$('#employeename').val(),
stateoforigine:$('#stateoforigine').val(),
employeephone: $('#employeephone').val(),
dateofbirth:$('#dateofbirth').val()
});
//Alter the slected data
localStorage.setItem("employees", JSON.stringify(employees));
return true;
});
for (var i in employees) {
var id = JSON.parse(localStorage.getItem(employees[i]));
}
Here is my code for the Edit button:
//register Edit button
$('.edit_button').live('click', function (e) {
alert('I was Cliked!');
e.stopPropagation();
$.each(employees, function(a, b) {
//if(b.id == employees[i]){
$('#id').val(b.id);
$('#employeeno').val(b.employeeno);
$('#employeename').val(b.employeename);
$("#stateoforigine").val(i.stateoforigine);
$('#employeephone').val(b.employeephone);
$('#dateofbirth').val(b.dateofbirth);
$("#id").attr("readonly","readonly");
$('#employeeno').focus();
$.mobile.changePage('#edit_employee_page');
return false;
//}
});
});
Here is my local Storage:
[
{"id":1,
"employeeno":"DEF/234/20014",
"employeename":"Bill Gates",
"stateoforigine":"Osun",
"employeephone":"080765432",
"dateofbirth":"12/11/1965"},
{"id":2,
"employeeno":"DEF/234/20014",
"employeename":"Bill Gates",
"stateoforigine":"Osun",
"employeephone":"080765432",
"dateofbirth":"12/11/1966"},
{"id":3,
"employeeno":"DEF/234/20014",
"employeename":"Bill Gates",
"stateoforigine":"Osun",
"employeephone":"080765432",
"dateofbirth":"12/11/1966"},
{"id":4,
"employeeno":"DAST/003/2003",
"employeename":"Gold Base",
"stateoforigine":"",
"employeephone":"",
"dateofbirth":"12/03/1986"}
]
Thanks for helping me out
The way you are storing your employees into localStorage is correct, but the way you are getting them out is incorrect. You stored your employees by stating:
localStorage.setItem("employees", JSON.stringify(employees));
So, in order to retrieve them, you must use:
var employees = JSON.parse(localStorage.getItem("employees"));
You see, you stored the data as a string with a key of "employees"; therefore, you can only retrieve it by that key. Since all data stored in localStorage is saved as a string, you must use JSON.parse() to convert the data back into an object - an array in this case. Then you can iterate over your employees.
Update:
You should be running this code as soon as the page is rendered (see below). I'm not sure how you're doing that - if you're using an IIFE or jQuery's document.ready() function. I don't think it's necessary to store an empty array into localStorage if none were loaded initially, so, I took your else clause out.
var employees = [];
if (localStorage.getItem('employees') !== null) {
employees = JSON.parse(localStorage.getItem('employees'));
}
Debug this line-by-line when it runs and make positive your employees variable contains data. If it doesn't contain data, well then, there's nothing to edit.
If, however, there is data, then execute your showEmployees() function. Oddly, I'm not seeing in your code where you actually call this. Is it bound to a button or action in your UI? Also, what is that for loop doing after your $('#edit_employee_page') click event function? It's trying to read data from localStorage improperly and it does nothing.
I think if you simply stepped through your code one line at a time using breakpoints and desk-checking your inputs/outputs you'd find out where you're going wrong.
It also appears that there's a disconnect in your code. May be you left out some lines; you define a string editEmployee but out of the blues you store JSON.stringify(employees) whereas employees is not defined in your code:
$('#edit_employee_page').on('click' , function(){
var editEmployee = JSON.stringify({
id: employees.length+1,
//........
});
//Alter the slected data
localStorage.setItem("employees", JSON.stringify(employees));
return true;
});
I had a similar task to do . I did it this way.
I passed the dynamic Id to be passed as an id attribute
id="'+empData.id+'"
and then inside the
$('.edit_button').live('click', function (e) {
alert('I was Cliked!');
var empId=$(this).attr('id');
rest of the code is same.

JavaScript: Getting two different value of dropdownlist selected index value

I have one dropdown list in my pgae. when I alert two continues times value of dropdown selected index I get two different value. Here is my code.
$(document).ready(function() {
// here code for getting data from server to bind dropdown
DoAjaxCall("?method=getDataForDDL&callbackmethod=BindDDL")
// after binding data to dropdown I wrote following two alert
alert(document.getElementById("ddlState").selectedIndex); //this alert -1
alert(document.getElementById("ddlState").selectedIndex); // this alert 0
alert(document.getElementById("ddlState").selectedIndex); // this alert 0
}
function BindDDL(data, msg) {// this function is called automatically after successfull AJAX call
var tbldata = eval('(' + data.toString() + ')'); //convert JSON data to Javascript Object
var ddl = document.getElementById("ddlState");
for (var i = 0; i < tbldata.Table.length; i++) {
ddl.options[ddl.length] = new Option(tbldata.Table[i][1], tbldata.Table[i][0]);
}
}
function DoAjaxCall(parameter){
//code for getting data from server by "POST" method
//After this function BindDDL is called which is call back function.
}
AJAX request are asynchronous, so you can't put your selected index checking code after the AJAX call; you have to put it in the callback to the AJAX request. Therefore, it's possible the first time you get -1, the list hasn't been populated with any data, but the second time it is.

Returning a value from a jQuery Ajax method

I'm trying to use Javascript in an OO style, and one method needs to make a remote call to get some data so a webpage can work with it. I've created a Javascript class to encapsulate the data retrieval so I can re-use the logic elsewhere, like so:
AddressRetriever = function() {
AddressRetriever.prototype.find = function(zip) {
var addressList = [];
$.ajax({
/* setup stuff */
success: function(response) {
var data = $.parseJSON(response.value);
for (var i = 0; i < data.length; i++) {
var city = data[i].City; // "City" column of DataTable
var state = data[i].State; // "State" column of DataTable
var address = new PostalAddress(postalCode, city, state); // This is a custom JavaScript class with simple getters, a DTO basically.
addressList.push(address);
}
}
});
return addressList;
}
}
The webpage itself calls this like follows:
$('#txtZip').blur(function() {
var retriever = new AddressRetriever();
var addresses = retriever.find($(this).val());
if (addresses.length > 0) {
$('#txtCity').val(addresses[0].getCity());
$('#txtState').val(addresses[0].getState());
}
});
The problem is that sometimes addresses is inexplicably empty (i.e. length = 0). In Firebug the XHR tab shows a response coming back with the expected data, and if I set an alert inside of the success method the length is correct, but outside of that method when I try to return the value, it's sometimes (but not always) empty and my textbox doesn't get populated. Sometimes it shows up as empty but the textbox gets populated properly anyways.
I know I could do this by getting rid of the separate class and stuffing the whole ajax call into the event handler, but I'm looking for a way to do this correctly so the function can be reused if necessary. Any thoughts?
In a nutshell, you can't do it the way you're trying to do it with asynchronous ajax calls.
Ajax methods usually run asynchronous. Therefore, when the ajax function call itself returns (where you have return addressList in your code), the actual ajax networking has not yet completed and the results are not yet known.
Instead, you need to rework how the flow of your code works and deal with the results of the ajax call ONLY in the success handler or in functions you call from the success handler. Only when the success handler is called has the ajax networking completed and provided a result.
In a nutshell, you can't do normal procedural programming when using asynchronous ajax calls. You have to change the way your code is structured and flows. It does complicate things, but the user experience benefits to using asynchronous ajax calls are huge (the browser doesn't lock up during a networking operation).
Here's how you could restructure your code while still keeping the AddressRetriever.find() method fairly generic using a callback function:
AddressRetriever = function() {
AddressRetriever.prototype.find = function(zip, callback) {
$.ajax({
/* setup stuff */
success: function(response) {
var addressList = [];
var data = $.parseJSON(response.value);
for (var i = 0; i < data.length; i++) {
var city = data[i].City; // "City" column of DataTable
var state = data[i].State; // "State" column of DataTable
var address = new PostalAddress(postalCode, city, state); // This is a custom JavaScript class with simple getters, a DTO basically.
addressList.push(address);
}
callback(addressList);
}
});
}
}
$('#txtZip').blur(function() {
var retriever = new AddressRetriever();
retriever.find($(this).val(), function(addresses) {
if (addresses.length > 0) {
$('#txtCity').val(addresses[0].getCity());
$('#txtState').val(addresses[0].getState());
}
});
});
AddressRetriever = function() {
AddressRetriever.prototype.find = function(zip) {
var addressList = [];
$.ajax({
/* setup stuff */
success: function(response) {
var data = $.parseJSON(response.value);
for (var i = 0; i < data.length; i++) {
var city = data[i].City; // "City" column of DataTable
var state = data[i].State; // "State" column of DataTable
var address = new PostalAddress(postalCode, city, state); // This is a custom JavaScript class with simple getters, a DTO basically.
addressList.push(address);
processAddresss(addressList);
}
}
});
}
}
function processAddresss(addressList){
if (addresses.length > 0) {
$('#txtCity').val(addresses[0].getCity());
$('#txtState').val(addresses[0].getState());
}
}
or if you want don't want to make another function call, make the ajax call synchronous. Right now, it is returning the array before the data is pushed into the array
Not inexplicable at all, the list won't be filled until an indeterminate amount of time in the future.
The canonical approach is to do the work in your success handler, perhaps by passing in your own callback. You may also use jQuery's .when.
AJAX calls are asynchroneous, which means they don't run with the regular flow of the program. When you execute
if (addresses.length > 0) {
addresses is in fact, empty, as the program did not wait for the AJAX call to complete.

Categories

Resources