Using AJAX to get dynamic data for Materialize autocomplete - javascript

​i've been struggling with this problem for the past 3 days or so and i'm wondering if anyone could help me with this. i have a form that has a textbox using autocomplete. what i want is to have the textbox get the data from an AJAX function and not just static data.
Based on the Materialize documentation, the way to get static data is by passing an object as the second argument upon initialization of an autocomplete instance:
let elem = document.querySelector('#brand');
let instance = M.Autocomplete.init(elem, { data: { "Apple": null, "Microsoft":null} });
​
Now since i want to use AJAX for dynamic data, i made an AJAX function and also another function to pass the data from the AJAX function to after success (this is to bypass the problem with using asyncronous functions), like so:
function ajaxCall() {
$.ajax({
type: 'GET',
url: 'showBrands',
dataType: 'json',
success: passData
});
}
function passData(data) {
return data;
}
After which, i tried to do the following but no luck though.
let elem = document.querySelector('#brand');
let instance = M.Autocomplete.init(elem, { data: ajaxCall() });
Am i doing something wrong here? Or is there a better approach? Any help is greatly appreciated. thanks in advance!

Try put your materialize plugin inside passdata function:
function ajaxCall() {
$.ajax({
type: 'GET',
url: 'showBrands',
dataType: 'json',
success: passData
});
}
function passData(data1) {
let elem = document.querySelector('#brand');
var instance = M.Autocomplete.getInstance(elem);
if (instance===null || instance===undefined){
instance = M.Autocomplete.init(elem, { data: data1 });
}else{
instance.updateData(data1);
}
}

Related

How to create callback function using Ajax?

I am working on the jquery to call a function to get the return value that I want to store for the variable email_number when I refresh on a page.
When I try this:
function get_emailno(emailid, mailfolder) {
$.ajax({
url: 'getemailnumber.php',
type: 'POST',
data : {
emailid: emailid,
mailfolder: mailfolder
},
success: function(data)
{
email_number = data;
}
});
return email_number;
}
I will get the return value as 6 as only when I use alert(email_number) after the email_number = data;, but I am unable to get the value outside of a function.
Here is the full code:
var email_number = '';
// check if page refreshed or reloaded
if (performance.navigation.type == 1) {
var hash = window.location.hash;
var mailfolder = hash.split('/')[0].replace('#', '');
var emailid = 'SUJmaWg4RTFRQkViS1RlUzV3K1NPdz09';
get_emailno(emailid, mailfolder);
}
function get_emailno(emailid, mailfolder) {
$.ajax({
url: 'getemailnumber.php',
type: 'POST',
data : {
emailid: emailid,
mailfolder: mailfolder
},
success: function(data)
{
email_number = data;
}
});
return email_number;
}
However, I have been researching and it stated that I would need to use callback via ajax but I have got no idea how to do this.
I have tried this and I still don't get a return value outside of the get_emailno function.
$.ajax({
url: 'getemailnumber.php',
type: 'POST',
async: true,
data : {
emailid: emailid,
mailfolder: mailfolder
},
success: function(data)
{
email_number = data;
}
});
I am getting frustrated as I am unable to find the solution so I need your help with this. What I am trying to do is I want to call on a get_emailno function to get the return value to store in the email_number variable.
Can you please show me an example how I could use a callback function on ajax to get the return value where I can be able to store the value in the email_number variable?
Thank you.
From the jquery documentation, the $.ajax() method returns a jqXHR object (this reads fully as jquery XMLHttpRequest object).
When you return data from the server in another function like this
function get_emailno(emailid, mailfolder) {
$.ajax({
// ajax settings
});
return email_number;
}
Note that $.ajax ({...}) call is asynchronous. Hence, the code within it doesn't necessarily execute before the last return statement. In other words, the $.ajax () call is deferred to execute at some time in the future, while the return statement executes immediately.
Consequently, jquery specifies that you handle (or respond to) the execution of ajax requests using callbacks and not return statements.
There are two ways you can define callbacks.
1. Define them within the jquery ajax request settings like this:
$.ajax({
// other ajax settings
success: function(data) {},
error: function() {},
complete: function() {},
});
2. Or chain the callbacks to the returned jqXHR object like this:
$.ajax({
// other ajax settings
}).done(function(data) {}).fail(function() {}).always(function() {});
The two methods are equivalent. success: is equivalent to done(), error: is equivalent to fail() and complete: is equivalent to always().
On when it is appropriate to use which function: use success: to handle the case where the returned data is what you expect; use error: if something went wrong during the request and finally use complete: when the request is finished (regardless of whether it was successful or not).
With this knowledge, you can better write your code to catch the data returned from the server at the right time.
var email_number = '';
// check if page refreshed or reloaded
if (performance.navigation.type == 1) {
var hash = window.location.hash;
var mailfolder = hash.split('/')[0].replace('#', '');
var emailid = 'SUJmaWg4RTFRQkViS1RlUzV3K1NPdz09';
get_emailno(emailid, mailfolder);
}
function get_emailno(emailid, mailfolder) {
$.ajax({
url: 'getemailnumber.php',
type: 'POST',
data : {
emailid: emailid,
mailfolder: mailfolder
},
success: function(data)
{
// sufficient to get returned data
email_number = data;
// use email_number here
alert(email_number); // alert it
console.log(email_number); // or log it
$('body').html(email_number); // or append to DOM
}
});
}

Use of global variable with ajax

Currently I am working on a website which uses asp.net and c#. I am getting data from the database using a web service and I get the correct data without an issue. However once I get the data via ajax call I need to assign it to a global variable which I later use to create a tree graph. This is where my problem comes, I've tried to assign the JSON object but I can't seem to get it to work. I keep getting an error
TypeError: treeData is undefined
Can someone guide me please. Below is the relevant code
Ajax Call
$(function () {
$.ajax({
type: "POST",
url: "MyService.asmx/SomeFunction",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: successHandler
});
});
SuccessHandler
function successHandler(data) {
var a = JSON.parse(data.d);
var b = [JSON.stringify(a)];
}
var treeData = successHandler[0]; //This part keeps giving me error
Thanks in advance for all your help and support.
You are trying to access successHandler as an array, when it is a function. You cannot use it like that. Instead, assign the [JSON.stringify(a)] to a global variable, and access that variable when you need the data, like so:
var dataFromAjax;
var treeData;
function successHandler(data) {
var a = JSON.parse(data.d);
dataFromAjax = [JSON.stringify(a)];
setTreeData();
}
function setTreeData() { //this function can be in the seperate script tag
treeData = dataFromAjax[0];
}
In this case you need to return the object from the function and use it like this successHandler()[0];
function successHandler(data) {
var a = JSON.parse('[{"a":1, "b":2}]');
return a; // you need to return the data from here.
}
var treeData = successHandler()[0]; //This part keeps giving me error
console.log(treeData)

wait for ajax result to bind knockout model

I have getGeneral function that calls ajax GET. When ajax recieves data (json), it creates KO model from given json and returns created KO.
When Knockout model is created and values are assigned, knockout applybindings should be called. Here is my code:
Defines GeneralModel and some related functions (inside "GeneralModel.js"):
var GeneralModel = function() {
//for now it is empty as data ar binded automatically from json
// CountryName is one of the properties that is returned with json
}
function getGeneral(pid) {
$.ajax({
url: "/api/general",
contentType: "text/json",
dataType: "json",
type: "GET",
data: { id: pid},
success: function (item) {
var p = new GeneralModel();
p = ko.mapping.fromJS(item);
return p;
},
error: function (data) {
}
});
}
This is called from another file (GeneralTabl.html), it should call get function and applyBindings to update UI:
var PortfolioGeneral = getGeneral("#Model.Id");
ko.applyBindings(PortfolioGeneral, document.getElementById("pv-portfolio-general-tab"));
However, in this scenario I am getting error (CountryName is not defined). This is because applyBindings happens before ajax returns data, so I am doing applyBindings to empty model with undefined properties.
Mapping from Json to Model happens here and is assignes values:
p = ko.mapping.fromJS(item);
I can also fill in GeneralModel with all fields, but it is not necessary (I guess):
var GeneralModel = function() {
CountryName = ko.observable();
...
}
It will still give an error "CountryName is not defined".
What is the solution?
1) Can I somehow move getGeneral inside GeneralModel, so get data would be part of GeneralModel initialization?
or
2) Maybe I should somehow do "wait for ajax results" and only then applyBindings?
or
I believe there are other options, I am just not so familiar with KO and pure JS.
Note: I fully understand that this is because Ajax is Async call, so the question is how to restructure this code taking into account that I have two seperate files and I need to call getGeneral from outside and it should return some variable.
Try using the returned promise interface:
function getGeneral(pid) {
return $.ajax({
url: "/api/general",
contentType: "text/json",
dataType: "json",
type: "GET",
data: {
id: pid
}
});
}
getGeneral("#Model.Id").done(function (item) {
var p = new GeneralModel();
p = ko.mapping.fromJS(item);
ko.applyBindings(p, document.getElementById("pv-portfolio-general-tab"));
}).fail(function () {
//handle error here
});

How to Bind Jquery Ajax to Parent

I got it to work with everyone's help. I change the 'context:' to 'this' from 'this.parentNode'. I still get confused with the 'this' context. With limited testing it appears to have fixed my problem with running multiple instances. Thanks for your help. The new code is shown below.
I am new to jQuery and Javascript. I am creating a general object to navigate database tables (NavDb). It works perfectly if I create 1 instance. When I run multiple instances it fails. I traced the problem to how I use 'this'. One routine that initializes/handles ajax requests fails. A form can have any number of selectors (autocomplete or drop-downs). The routine recursively performs ajax requests until all the selectors have been initialized. The 'this' variable refers to the ajax object when entering the 'success:' function. I need a reference to the parent object so I created a $this on line 2. The problem is it creates a closure and messes up the second instance (I believe that is what is happening). How do I get a reference to the parent object inside the success function? Can I bind the ajax request to the parent object? I need something like this:
var $this = this.parent;
Hopefully I explained this clearly.
New code
NavDb.prototype.getSelData = function () {
if (this.curSelector >= this.selectors.length) {
return;
}
else {
var sql = this.selectors[this.curSelector].sql;
$.ajax({
url: 'php/select.php',
type: 'POST',
context: this, // Only needed 'this' not this.parentNode.
dataType: 'json',
data: {
'sql': sql
}
}).done(function (data) {
if (data.success) {
if (data.v.length > 0) {
this.selectors[this.curSelector].data = data;
if (this.selectors[this.curSelector].type == "autoComp") {
this.initAC();
};
if (this.selectors[this.curSelector].type == "dropDown") {
this.initDD();
};
}
}
this.curSelector++;
this.getSelData();
}).fail(function (XHR, textStatus, errorThrown) {
$("#status").html(getErrorText(XHR.responseText));
});
};
};
Old code
NavDb.prototype.ajaxSelData = function () {
var $this = this;
if (this.curSelector >= this.selectors.length) {
$this = null;
return;
}
else {
var sql = $this.selectors[$this.curSelector].sql;
$.ajax({
url: 'php/select.php',
type: 'POST',
dataType: 'json',
data: {
'sql': sql
},
success: function (data) {
if (data.success) {
if (data.v.length > 0) {
$this.selectors[$this.curSelector].data = data;
if ($this.selectors[$this.curSelector].type == "autoComp") {
$this.initAC();
};
if ($this.selectors[$this.curSelector].type == "dropDown") {
$this.initDD();
};
}
} else {
alert(data.error);
}
$this.curSelector++;
$this.ajaxSelData();
}
});
};
};
For correct context scope see this answer.
You can ensure correct context in several ways:
use context
$.ajax({
url: 'php/select.php',
type: 'POST',
context: this.parentNode,
dataType: 'json',
data: {
sql: sql
},
success: function (data) {
// 'this' is parentNode
}
})
use closure
var parentNode = this.parentNode;
success: function (data) {
//you can now use 'parentNode'
}
use $.proxy
$.proxy(function(data){
// 'this' is parentNode
}, this.parentNode);
The closure your code creates is unique to each instance (it creates a separate closure for each instance) so your theory that the closure was messing up the second instance is not correct.
So, creating your separate variable as you were doing with:
var $this = this;
is a perfectly fine thing to do and will not cause problems.
But, if you want the parent node, then perhaps you should be doing this:
var parent = this.parent;
and then refer to the parent variable inside your ajax function.
You could also just pass the context argument to your ajax call and that will set the this parameter as desired in the success handler callback.
$.ajax({
url: 'php/select.php',
type: 'POST',
dataType: 'json',
context: this.parent, // add this line
data: {
'sql': sql
},
success: function (data) {
// now the this pointer is set as desired in your callback here
if (data.success) {

jquery trouble with getJSON call

Got some basic problem again.
I need to modify a function that previously returned a in code written object.
Im now trying to get the object from json through $.getJSON
function getEventData() {
var result = '';
$.getJSON("ajax.php?cmd=getbydate&fromdate=&todate=", function(data) {
result = data;
});
return result;
}
Problem is that result isn't set in the callback function for obvious reasons.
Do you guys have a solution for this?
Edit:
Ok i got an answer that was removed.
I just had to change it abit..
This is the answer that works:
function getEventData() {
var result = '';
url = "ajax.php?cmd=getbydate&fromdate=&todate=";
$.ajax({
url: url,
async: false,
dataType: 'json',
success: function(data) {
result = data;
}
});
return result;
}
You should program your application in an asynchronous way, which means, that you should use callback functions for you application flow, too, or continue in the getJson callback function. You can also make the request synchronously which should then be able to return the value (or at least assign it and block the function till the callback is completed), but this is not recommended at all:
function getEventData() {
var result = '';
result = $.ajax({
url: "ajax.php?cmd=getbydate&fromdate=&todate=",
async: false,
dataType: "json",
data: data,
success: function(data) {
return data;
}
});
return result;
}
Are you sure that the server returns valid json? It will be better to validate it using a tool like jsonlint. Also make sure that application/json is used as content type for the response.

Categories

Resources