Accepted use methods of javascript callbacks - javascript

I am looking for advice to ensure that I am using callbacks and javascript coding using generally accepted js guidelines. What is listed below is two functions which are chained together. Basically its a list of checks which need to be completed prior to creating the entity. I don't expect the final version to use a ajax POST but it is a good way to test all of the error handling.
Advice or recommendations would be appreciated!! I will give credit to the best explained and critiqued answer.
function relationship_check(app_label, model, company_id, params, form, callback_function){
// This will check to see if a relationship exists. This works even on new objects.
kwargs = $.extend({}, params);
kwargs['app_label'] = app_label;
kwargs['model'] = model;
kwargs['relationship__company'] = company_id;
kwargs['error_on_objects_exists_and_no_relation'] = true;
ajax_req = $.ajax({
url: "{% url 'api_get_discover' api_name='v1' resource_name='relationship' %}",
type: "GET",
data: kwargs,
success: function(data, textStatus, jqXHR) {
callback_function(form, params)
},
error: function(data, textStatus, jqXHR) {
results = $.parseJSON(data.responseText)
if (results['object_exists'] && ! results['relationships_exists']){
django_message(results['create_string'], "info");
} else {
django_message(results['error'], "error");
}
return false
}
})
return false
};
function create_community(form, data){
var self = $(this),
ajax_req = $.ajax({
url: self.attr("action"),
type: "POST",
data: data,
success: function(data, textStatus, jqXHR) {
django_message("Saved successfully.", "success");
},
error: function(data, textStatus, jqXHR) {
var errors = $.parseJSON(data.responseText);
$.each(errors, function(index, value) {
if (index === "__all__") {
console.log(index + " : " + value )
django_message(value[0], "error");
} else {
console.log(index + " : " + value )
apply_form_field_error(index, value);
}
});
}
});
}
$(document).on("submit", "#community_form", function(e) {
e.preventDefault();
clear_form_field_errors("#community_form");
var data = {
name: $(this).find("#id_name").val(),
city: $(this).find("#id_city").val(),
cross_roads: $(this).find("#id_cross_roads").val(),
website: $(this).find("#id_website").val(),
latitude: $(this).find("#id_latitude").val(),
longitude: $(this).find("#id_longitude").val(),
confirmed_address: $(this).find("#id_confirmed_address").val()
};
console.log(data)
relationship_check(
'community', 'community', '{{ request.user.company.id }}',
data, "#community_form", create_community);
});

Related

Access object properties - Ajax Call

I have simple AJAX call.
It looks like this:
myApp.onPageInit('about', function (page) {
search_term = $$("#search_term").val();
const key = "xxxx-xxxx";
const nick = "https://api.xxx.xxx/" + search_term + "?api_key=" + key;
$$.ajax({
url:nick,
type:'GET',
dataType: JSON,
beforeSend: function(){
//myApp.showPreloader('Please wait...');
},
success: function(data) {
//myApp.hidePreloader();
console.log(data);
console.log(data['summonerLevel']);
},
statusCode: {
404: function() {
// myApp.alert('Account does not exist.', 'ERROR');
}
},
error: function(data) {
myApp.alert('Account does not exist.', 'ERROR');
// ak je ovaj error, netko je dirao putanju - fajl
},
});
})
When I'm trying to get properties from data object, every time it says undefined.
Console log: {"id":"xxxx","accountId":"xxxx","puuid":"xxxx","name":"Data","profileIconId":3015,"revisionDate":1546082318000,"summonerLevel":37}
Second console log: undefined
I tried dot notation and bracket notation, but everytime same status(undefined).
Like this:
console.log(data['summonerLevel']);
console.log(data.summonerLevel);
Any suggestion for this problem?
use JSON.Parse() method and try taking the value with object.attributename
$.ajax({
url:nick,
type:'GET',
dataType: JSON,
beforeSend: function(){
},
success: function(data) {
var data=JSON.Parse(data);
console.log(data.summonerLevel);
console.log(data.accountId);
},
statusCode: {
404: function() {
}
},
error: function(data) {
},
});

pass two variable inside ajax data call in jquery function

I get two variable in my jquery function and how i pass it in my data inside ajax call and get it in laravel controller
This is my function
$('#updateProduct').on('submit', function(e){
e.preventDefault(e);
var redirect_url = $(this).find("[name='redirect_url']").val();
var url = $(this).attr('action');
var method = $(this).attr('method');
var videos = document.getElementById('videoToUpload').files[0];
var myData ={
'name': $(this).find("[name='name']").val(),
'description': $(this).find("[name='description']").val(),
'brand': $(this).find("[name='brand']").val(),
'category': $(this).find("[name='category']").val(),
'condition': $(this).find("[name='condition']").val(),
'shipper': $(this).find("[name='shipper']").val(),
'shipping_from': $(this).find("[name='shipping_from']").val(),
'shipping_paid_by': $(this).find("[name='shipping_paid_by']").val(),
'shipping_within' :$(this).find("[name='shipping_within']").val(),
'shipping_weight': $(this).find("[name='shipping_weight']").val(),
'shipping_fee': $(this).find("[name='shipping_fee']").val(),
'seller_get' : $(this).find("[name='seller_get']").val(),
'price_per_unit': $(this).find("[name='price_per_unit']").val(),
'selling_fee' : $(this).find("[name='selling_fee']").val(),
'is_active':$(this).find("[name='is_active']:checked").val(),
//'videos' :$("#videoToUpload").files[0],
//'videos' : document.getElementById('videoToUpload').files[0],
}
console.log(data);
$.ajax({
type: method,
url: url,
dataType: 'JSON',
data: {'myData':myData
'videos':new FormData("videos", document.getElementById('videoToUpload').files[0])
},
success: function(data){
alert("Products updated successfullly");
console.log(data);
//window.location.href = redirect_url;
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(JSON.stringify(jqXHR));
console.log("AJAX error: " + textStatus + ' : ' + errorThrown);
}
});
Here i am having two variable one videos and other myData now my question is how to pass these two variable in data and request this variable in laravel controller
You have done everything well, but forget to write comma
$.ajax({
type: method,
url: url,
dataType: 'JSON',
data: {'myData': myData, 'videos': new FormData("videos", document.getElementById('videoToUpload').files[0]) },
success: function(data){
// .........
},
error: function(jqXHR, textStatus, errorThrown) {
// .........
}
});
By the way, don't spend time to define each input to variable, use jquery serialize and PHP unserialize, or you can use this code below to create Serialize Object
$.fn.serializeObject = function() {
var o = {};
var a = this.serializeArray();
$.each(a, function() {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};

Working with two URLs in ajax

I have to get values from two different URLs and then to merge it. I know it would much better if i'll get all of the data in one URL, but that's how i've got and i need to work with it.
I want to print out the value of a_value, but it's been printed out while b hasn't returned his value. I've read some articles of how to make the functions synchronous but still don't know how to implement it into my code, and don't know what is the best solution for my case. I'm pretty new with JavaScript and still need some help and guiding.
function any_function() {
$.ajax(
{
url : '/url1',
type: "GET",
success:function(data, textStatus, jqXHR)
{
$("#print").html(a(data));
}
});
}
function a(data){
x = 'any value' //`do something with data and insert to this variable`
a_value = x + b(`some id that extracted from data`)
return a_value
}
function b(id){
$.ajax({
url: '/url2',
type: 'GET',
success: function (data, textStatus, jqXHR) {
b_value = c(data, id)
}
});
return b_value
}
function c(data, id){
//do something with `data` and return the value
return c_value
}
function f() {
var request1 = $.ajax({
url : '/url1',
type: 'GET'
});
var request2 = $.ajax({
url: '/url2',
type: 'GET'
});
$.when(request1, request2).done(function(result1, result2){
data1 = result1[0]
data2 = result2[0]
// r1 and r2 are arrays [ data, statusText, jqXHR ]
// Do stuff here with data1 and data2
// If you want to return use a callback or a promise
})
}
This can be done in a synchronous-looking fashion with promises:
$.get(url1)
.then(function(data1){
return $.get(url2)
})
.then(function(data2){
return $.get(url3);
})
.then(function(data3){
// All done
});
You just need to make the second call in the success handler of the first one:
function any_function() {
$.ajax({
url : '/url1',
type: "GET",
success:function(data, textStatus, jqXHR) {
$("#print").html(a(data));
b("someId");
}
});
}
function a(data){
x = 'any value' //`do something with data and insert to this variable`
a_value = x + b(`some id that extracted from data`)
return a_value;
}
function b(id){
$.ajax({
url: '/url2',
type: 'GET',
success: function (data, textStatus, jqXHR) {
b_value = c(data, id);
return b_value;
}
});
}
function c(data, id){
//do something with `data` and return the value
return c_value
}

Select2: Uncaught TypeError: options.results is not a function

I am attempting to do an AJAX call with the Select2 jquery plugin. The query seems to be working, but the issue occurs when .results() is called on the options object:
Uncaught TypeError: options.results is not a function
Here is my HTML:
<input class="form-control" type="number" value="2125" name="topic_relation[source_topic_id]" id="topic_relation_source_topic_id" />
Here is my JS:
$(document).ready(function() {
$('#topic_relation_source_topic_id').select2({
minimumInputLength: 3,
ajax: {
url: "<%= grab_topics_path %>",
dataType: 'json',
delay: 250,
data: function (term, page) {
return {
q: term, //search term
page_limit: 30, // page size
page: page, // page number
};
},
processResults: function (data, page) {
var more = (page * 30) < data.total;
return {results: data.topics, more: more};
}
},
formatResult: topicFormatResult,
formatSelection: formatRepoSelection,
escapeMarkup: function (m) { return m; }
});
function topicFormatResult(topic) {
return topic.name
}
function formatRepoSelection(topic) {
return '<option value="'+ topic.id +'">' + topic.name + '</option>'
}
});
Here is the returned JSON:
{"total":2, "topics":[{"id":305,"name":"Educational Assessment, Testing, And Measurement"},{"id":3080,"name":"Inspectors, Testers, Sorters, Samplers, And Weighers"}]}
Here is the code which is failing:
function ajax(options) {
var timeout, // current scheduled but not yet executed request
handler = null,
quietMillis = options.quietMillis || 100,
ajaxUrl = options.url,
self = this;
return function (query) {
window.clearTimeout(timeout);
timeout = window.setTimeout(function () {
var data = options.data, // ajax data function
url = ajaxUrl, // ajax url string or function
transport = options.transport || $.fn.select2.ajaxDefaults.transport,
// deprecated - to be removed in 4.0 - use params instead
deprecated = {
type: options.type || 'GET', // set type of request (GET or POST)
cache: options.cache || false,
jsonpCallback: options.jsonpCallback||undefined,
dataType: options.dataType||"json"
},
params = $.extend({}, $.fn.select2.ajaxDefaults.params, deprecated);
data = data ? data.call(self, query.term, query.page, query.context) : null;
url = (typeof url === 'function') ? url.call(self, query.term, query.page, query.context) : url;
if (handler && typeof handler.abort === "function") { handler.abort(); }
if (options.params) {
if ($.isFunction(options.params)) {
$.extend(params, options.params.call(self));
} else {
$.extend(params, options.params);
}
}
$.extend(params, {
url: url,
dataType: options.dataType,
data: data,
success: function (data) {
========> var results = options.results(data, query.page, query); <==========
query.callback(results);
},
error: function(jqXHR, textStatus, errorThrown){
var results = {
hasError: true,
jqXHR: jqXHR,
textStatus: textStatus,
errorThrown: errorThrown
};
query.callback(results);
}
});
handler = transport.call(self, params);
}, quietMillis);
};
}
Since the plugin calls results(), you should also declare results: function (data, page) instead of processResults: function (data, page).

how to wait for model initialize before starting view

I am making a basic trello clone. Except instead of signing in, projects have a slug(i.e. 'www.example.com/1d754b6c')
If a user visits the root, a new slug is created on the back end. The user is then routed to www..com/1d754b6c, which sends another ajax call to get the projects ID. A view is then started. However my view is getting started before the slug -> ID ajax call is finished. Whats the best way to fix this? (I currently have a setTimeout as a temporary patch, I know that is not a good way to accomplish this)
router.js
Buckets.Routers.PageRouter = Backbone.Router.extend({
routes: {
'': 'newProject',
':token': 'displayProject'
},
newProject: function () {
new Buckets.Models.Project({});
},
displayProject: function (token) {
var that = this;
var project = new Buckets.Models.Project({token: token});
setTimeout(function(){
new Buckets.Views.showProject({
model: project
});
}, 500);
}
});
project.js
Buckets.Models.Project = Backbone.Model.extend({
url: function() {
return Buckets.BASE_URL + '/api/projects/' + (this.id)
},
initialize: function(options) {
var that = this;
if (options && options.token) {
that.token = options.token
$.ajax({
url: Buckets.BASE_URL + '/' + that.token,
dataType: 'json',
success: function( data, status ){
that.id = data;
},
error: function(xhr, textStatus, err) {
console.log(xhr);
}
});
} else {
$.ajax({
url: Buckets.BASE_URL + '/api/projects/new',
dataType: 'json',
success: function( data, status ){
that.token = data.token;
that.id = data.id;
Buckets.Routers.router.navigate('/' + that.token, true);
},
error: function(xhr, textStatus, err) {
console.log(xhr);
}
});
}
return this;
},
});
Try to use Backbone.Model.sync. .sync() returns a Promise so you can take full advantage of the Deffered/Promises standard.
When I want to pass variable urls to the fetch I override the model.fetch(). For your implemenation I'd first scrap the $.ajax in initialize() and override fetch like this
Buckets.Models.Project = Backbone.Model.extend({
fetch: function(options) {
var that = this;
if (options && options.token) {
this.url = Buckets.BASE_URL + '/' + that.token;
else
this.url = Buckets.BASE_URL + '/api/projects/new';
return Backbone.Model.prototype.fetch.call(this, options);
}
.fetch() eventually returns the result of sync() which is a Promise. That means that in your Router you'd do this:
displayProject: function (token) {
var that = this;
var project = new Buckets.Models.Project();
$.when(project.fetch({token: token})
// deffered.done() replaces the success callback in your $.ajax
.done(function() {
project.id = data;
new Buckets.Views.showProject({ model: project });
})
// deffered.fail() replaces the error callback in your $.ajax
.fail(function( jqXHR, textStatus, errorThrown) {
console.log(jqXHR);
});
}
And for completeness, you'd reweite newProject() similarly,
newProject: function () {
var project = new Buckets.Models.Project();
$.when(project.fetch({token: token})
.done(function( data, textStatus, jqXHR ) {
project.token = data.token;
project.id = data.id;
new Buckets.Views.showProject({ model: project });
})
.fail(function( jqXHR, textStatus, errorThrown) {
console.log(jqXHR);
});
}
Try it out. I started using this method of fetching when it was recommended to me by a major contributor to MarionetteJS, one of the premier opinionated Backbone frameworks. This method is easy to maintain and very responsive.

Categories