Shopify Ajax API is not accepting properties - javascript

I am trying to pass three products through the shopify ajax api. It sends over the variant id and quantity but not the properties. the code is below. if I add request.properties to the Shopify.addItem function it stops after one item and gives me a pop saying that one item has been added to the cart. It does not add the other two items nor does it redirect. If I remove request.properties from the Shopify.addItem function it adds all three items to the cart but with no properties.
FINAL CODE Revised from #miglio code
var FreeTrial={
data:[],
ini:0,
total:0,
addItem:function(qty,id,properties,callback) {
var params = {quantity:qty,id:id};
if(properties != false){
params.properties = properties;
}
$.ajax({
type: 'POST',
url: '/cart/add.js',
dataType: 'json',
async:false,
data: params,
success: function(){
if(typeof callback === 'function'){
callback();
}
},
error: function(){}
});
},
recursive:function(){
FreeTrial.addItem(FreeTrial.data[FreeTrial.ini].qty,FreeTrial.data[FreeTrial.ini].id,FreeTrial.data[FreeTrial.ini].properties,function(){
//console.log(FreeTrial.data[FreeTrial.ini]);
FreeTrial.ini += 1;
if(FreeTrial.ini < FreeTrial.total){
FreeTrial.recursive();
}else{
//return false;
document.location.href = '/cart';
}
});
},
begin:function(){
/* SET YOUR ARRAY QTY's' ID's*/
FreeTrial.data = [
{
"qty": '1',
"id": 'VARIANT_ID_GOES_HERE',
"properties": false
},
{
"qty": '1',
"id": 'VARIANT_ID_GOES_HERE',
"properties": false
},
{
"qty": '1',
"id": 'VARIANT_ID_GOES_HERE',
"properties": false
},
{
"qty": '1',
"id": 'VARIANT_ID_GOES_HERE',
"properties": false
},
{
"qty": '1',
"id": 'VARIANT_ID_GOES_HERE',
"properties": {
"recurring_price": "200.00",
"shipping_interval_frequency": "30",
"shipping_interval_unit_type": "days",
"subscription_id": "12599"
}
}
];
FreeTrial.total = FreeTrial.data.length;
FreeTrial.recursive();
}
}
FreeTrial.begin();

To add properties I use this function and work fine for me.
addItem=function(qty,id,properties,callback) {
var params = {quantity:qty,id:id};
if(properties != false){
params.properties = properties;
}
$.ajax({
type: 'POST',
url: '/cart/add.js',
dataType: 'json',
data: params,
success: function(){
if(typeof callback === 'function'){
callback();
}
},
error: function(){}
});
}
//Example :
var qty = 1;
var id = 123456;//variant_id
var properties: {
"recurring_price": "12",
"shipping_interval_frequency": "34",
"shipping_interval_unit_type": "56",
"subscription_id": "78"
}
//
addItem(qty,id,properties,function(){
console.log('done');
});
Well, I did this code for multiple items and a save in a gist:
multiple add to cart

Any POST to the endpoint url: '/cart/add.js', can include properties. If the properties are setup correctly, it works like a charm. You can assign as many properties to a variant as you want. Has been working for what, 5 years now? This function has been working for that long at least... no trouble.
addItemWithProperties: function(variant_id, quantity, properties, callback) {
var quantity = quantity || 1;
if(properties) {
var data = properties.join("&")+"&quantity="+quantity+"&id="+variant_id;
} else {
var data = "quantity="+quantity+"&id="+variant_id;
}
var params = {
type: "POST",
url: "/cart/add.js",
data: data,
dataType: "json",
success: function(line_item) {
if((typeof callback) === "function") {
callback(line_item)
} else {
Shopify.onItemAdded(line_item)
}
},
error: function(XMLHttpRequest, textStatus) {
Shopify.api.onError(XMLHttpRequest, textStatus)
}
};
$.ajax(params)
},

edit. I guess you could do the call manually
add to cart
Considering the Shopify.addItem() function is, straight off their API I'm not sure you can simply add a parameter like that.
My guess is that the extra parameter has the effect that the function doesn't run.

Related

Unable to bind json data (api result) to dropdown using jquery/js in MVC

I want to bind json data returned by API to dropdownlist.
but unable to fetch value id and name.
Json Format :
{
"categories": [
{
"categories": {
"id": 1,
"name": "CatOne"
}
},
{
"categories": {
"id": 2,
"name": "CatTwo"
}
}
]
}
I am returning JsonResult, using
return Json(responseData, JsonRequestBehavior.AllowGet);
and in Jquery call ,I am using
$.ajax({
type: "POST",
url: "/Home/City",
contentType: "application/json; charset=utf-8",
global: false,
async: false,
dataType: "json",
success: function (jsonObj) {
var listItems = "";
//here I want to get id and name
});
}
});
You can populate dropdown from your json like following.
var json = {
"categories": [
{ "categories": { "id": 1, "name": "CatOne" } },
{ "categories": { "id": 2, "name": "CatTwo" } }
]
}
$.each(json.categories, function () {
$('select').append('<option value="' + this.categories.id + '">' + this.categories.name + '</option>')
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select></select>
You can just stick a break point (or debugger; statement) inside your success callback. Then you can inspect your jsonObj and it'll tell you exactly what you need to know.
In this case, you should be able to iterate on jsonObj.categories, and your id and name properties will be accessible via jsonObject.categories[i].categories.id and jsonObject.categories[i].categories.name
So your success method will look something like:
for(var i = 0; i < jsonObj.categories.length; i++) {
var category = jsonObj.categories[i].categories;
var id = category.id;
var name = category.name;
}
I would also suggest formatting your json differently, as other answers have suggested.

Create datatable in js via json data in a variable?

now I encounter a problem. I want to use ajax to show a datatable via using data coming from sql server database. Current state is I have used ajax to call a Handler.ashx to connect sql server and convert the data to json (using newtonsoft.json). In ajax, all json data has been recevied from Handler.ashx and stored in a variable "msg" which could be successfully showed on page. I want to put this "msg" into a datatable but failed all the time. I tried almost all methods online to set the datatable but still give different errors. I want to create a datatable in js and fill in my json data. But the result is either null or no data available in table.
Here is the codes and json data looks like.
js:
$(document).ready(function () {
$("#eventsButton").click(function () {
$.ajax({
type: "POST",
url: "../Handler.ashx",
//contentType: "application/json",
data: { postcode: $("#eventsPostcodeTextbox").val() },
cache: false,
success: function (msg) {
//for (var i in msg) {
// $("#eventGrid").append(msg[i]);
//}
//var jsonStr = JSON.stringify(msg);
document.getElementById("result").innerHTML = msg;
$('#eventtable').dataTable({
//"paging": false,
//"searching": false,
//"retrieve": true,
//"bProcessing": true,
//"data": msg.data,
//"datatype": "JSON",
//"ajax": "HandlerAll.ashx",
//"aaData": JSON.parse(msg),
//"ajax":
//"dataSrc":virtualTable
//"aoColumns": [
// { "mData": "ID" },
// { "mData": "FESTIVAL" },
// { "mData": "SUBURB" },
// { "mData": "POSTCODE" },
// { "mData": "WEBSITE" },
// { "mData": "DESCRIPTION" }
// ]
});
},
error: function (data) {
alert("Server error.");
}
})
});
});
json data (the size depends on the search condition, the table columns should have "ID","Festival" and so on, but no "virtualTable"):
{ "virtualTable": [ { "ID": "1", "FESTIVAL": "Antipodes Festival", "SUBURB": "Lonsdale Street, Melbourne", "POSTCODE": "3000", "WEBSITE": "http://www.antipodesfestival.com.au/", "DESCRIPTION": "The greek precinct in melbourne cbd will transform into a huge, free street festival with the hosting of the antipodes lonsdale street festival which will hold sway from 14 february 2015 to 15 february 2015." }, { "ID": "5", "FESTIVAL": "Boite Singers Festival", "SUBURB": "Victoria", "POSTCODE": "3000", "WEBSITE": "http://boite.com.au/index.php", "DESCRIPTION": "The boite singers festival brings you four days of vocal inspiration and sheer fun on the second weekend of january each year." } ] }
Since you get a JSON as reponse, I would try to convert it to JSON object, take the virtualTable part that it is a set of records in JSON and convert it to an array to add it to my table.
$(document).ready(function () {
$("#eventsButton").click(function () {
$.ajax({
type: "POST",
url: "../Handler.ashx",
// dataType: "json",
data: { postcode: $("#eventsPostcodeTextbox").val() },
success: function (msg) {
var jdata = $.parseJSON(msg);
jdata = jdata.virtualTable;
if (jdata.length != 0) {
var array_data = [];
var temp_array = [];
$(jdata).each(function(key, value) {
temp_array = [];
temp_array = [value.ID,
value.FESTIVAL,
value.SUBURB,
value.POSTCODE,
value.WEBSITE,
value.DESCRIPTION
];
array_data[array_data.length] = temp_array;
});
$('#eventtable').dataTable().fnAddData(array_data);
$('#eventtable').dataTable().fnDraw();
},
error: function (data) {
alert("Server error");
}
SOLUTION
Use the code below to initialize the table:
$('#eventtable').dataTable({
data: msg.virtualTable,
columns: [
{ data: "ID" },
{ data: "FESTIVAL" },
{ data: "SUBURB" },
{ data: "POSTCODE" },
{ data: "WEBSITE" },
{ data: "DESCRIPTION" }
]
});
DEMO
See this jsFiddle for code and demonstration.

Array not passing from Javascript to MVC

I'm trying to pass an array from javascript back into my MVC app. There is a console.log(selected) in the javascript and it outputs an array of data:
["<img src="https://owlexpress.kennesaw.edu/stugifs/open.gif">", "MATH 1190/01 - Calculus I", "84528", " 4.000", "Full Term", "40", "34", "6", "0", "0", "0", "Kennesaw Campus", "Classroom - 100%", "Mathematics & StatisticsRoom 108", "8:00 am - 9:10 amLecture", "Aug 17, 2015", "Dec 14, 2015", "Xiaohui Rebecca Shi (P)", ""]
But when the breakpoint in the controller hits I see that selectedClassesArray == null
Javascript:
$('#WatchButton').on('click', function (e) {
var selected = [];
$("tr.selected").each(function () {
$(this).find('td').each(function(){
selected.push($(this).html());
});
});
console.log(selected);
$.ajax({
type: "POST",
url: "/ClassSearch/watchClasses",
// I have tried setting data both ways with the same result:
//data: { selectedClassesArray: selected },
data: [selected],
traditional: true,
success: function (data) { alert("SUCCESS"); }
});
});
ViewModel:
public class SelectedClassesArray
{
public string[] arrayOfClasses { get; set; }
}
Controller ACtion:
//Had to set ValidateInput to false since one of the strings contains < (it errored without this)
[HttpPost, ValidateInput(false)]
public ActionResult watchClasses(IEnumerable<SelectedClassesArray> selectedClassesArray)
{ //Breakpoint here shows that selectedClassesArray is null
foreach (var item in selectedClassesArray)
{
Console.WriteLine(item.ToString());
}
return View();
}
Your action is expecting a List of arrays:
watchClasses(IEnumerable<SelectedClassesArray> selectedClassesArray)
You probably want to get only the array, which is in the view model:
watchClasses(SelectedClassesArray selectedClassesArray)
And what #taxicala said makes sense, try passing only the array, not an array inside another array:
data: { selectedClassesArray: selected }
The posted property name must match the view model parameter's name.
Did you try:
$.ajax({
type: "POST",
url: "/ClassSearch/watchClasses",
// I have tried setting data both ways with the same result:
//data: { selectedClassesArray: selected },
data: selected,
traditional: true,
success: function (data) { alert("SUCCESS"); }
});
Or perhaps the traditional serialization is failing:
$.ajax({
type: "POST",
url: "/ClassSearch/watchClasses",
// I have tried setting data both ways with the same result:
//data: { selectedClassesArray: selected },
data: { selectedClassesArray: selected },
traditional: false,
success: function (data) { alert("SUCCESS"); }
});

Starting at a specific index in each function

Please take a look at this fiddle
How can I use slice in the loop to make it return results starting from a specific index?
The JSON file:
[
{
"title": "A",
"link": "google.com",
"image": "image.com",
"price": "$1295.00",
"brand": "ABC",
"color": "Black",
"material": "Rubber"
}
]
I want it to return results starting from brand:
brand - ABC
color - Black
material - Rubber
I don't know where to put .slice(4) in the loop. I got undefined error using
$.each(value.slice(4),function(key, value)
Here's the code:
JS:
$.ajax({
url: "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20json%20where%20url%20%3D%22http%3A%2F%2Fgoo.gl%2FaZgYDB%22&format=json&diagnostics=true&callback=",
success: function (data) {
var item_html="";
$(data.query.results.json).each(function(key, value) {
$.each(value,function(key, value){
item_html += '<h3>'+key+' - '+value+'</h3>';
});
});
$('#area').append(item_html);
}
});
Use a separate array of property names, so you can slice it and get the names in a guaranteed order.
var props = [
"title",
"link",
"image",
"price",
"brand",
"color",
"material"
];
$.ajax({
url: "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20json%20where%20url%20%3D%22http%3A%2F%2Fgoo.gl%2FaZgYDB%22&format=json&diagnostics=true&callback=",
dataType: 'json',
success: function (data) {
var item_html="";
var propslice = props.slice(4);
$.each(data.query.results.json, function(i, obj) {
$.each(propslice, function(i, key) {
value = obj[key];
item_html += '<h3>'+key+' - '+value+'</h3>';
});
});
$('#area').append(item_html);
}
});
If there are a small number of properties you want to skip, you can make a list of them in an object, and test against that list:
var excluded_props = {
title: true,
link: true,
image: true,
price: true
};
$.ajax({
url: "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20json%20where%20url%20%3D%22http%3A%2F%2Fgoo.gl%2FaZgYDB%22&format=json&diagnostics=true&callback=",
dataType: 'json',
success: function (data) {
var item_html="";
$.each(data.query.results.json, function(i, obj) {
$.each(obj, function(key, value) {
if (!excluded_props[key]) {
value = obj[key];
item_html += '<h3>'+key+' - '+value+'</h3>';
}
});
});
$('#area').append(item_html);
}
});
What you're asking for isn't possible with an object. Objects in Javascript are not ordered, only arrays. You have a few options:
Refactor your object to be an array
Refactor your object so that each key has a new key for order*
loop through each property of the object, placing it into an array (no guaranteed order!) and then looping through the array.
*Example:
[
{
"title": {
"value" : "A",
"order" : 4
},
"link": {
"value" : "google.com",
"order" : 5
...
}
]

Filter select options based on data-* attribute

I have 2 select menus on my page.
First have 3 values: All, Active, Unactive and second is filled with data that comes from server.
I need to connect them, so that when I select an option from the first select menu, the second select will have only certain options (filter second select menu)
My idea was to get data from server with 3 elements:
[ { "Id": 1, "Name": "Active One", "Active":true },
{ "Id": 2, "Name": "Active Two", "Active":true },
{ "Id": 3, "Name": "Unactive One", "Active":false },
{ "Id": 4, "Name": "Unactive Two", "Active":false } ]
Second thing that I do is adding all options with custom attribute to that select:
<option value=' + n[index].Id + ' data-active='+n[index].Active+'>' + n[index].Name + '</option>
I have problem with filtering second select.
I've wrapped filling second select inside a plugin so it will be easier to reuse it.
Here is jsFiddle demo: http://jsfiddle.net/Misiu/pr8e9/4/
What I would like this to work is after filling select from server user will be able to select every option from second select, but when he will change first select the second one will update-show only appropriate options.
So if he'll select Active he will be able to select only Active One or Active Two.
EDIT: This is working solution thanks to #oe.elvik
Alternative solution:
(function ($) {
var meinData;
$.fn.createOptions = function(filter) {
var $this = this;
var n = meinData
var list = "";
for (var index = 0; index < n.length; index++) {
if(filter == -1 || (filter == 1 && n[index].Active) || (filter == 0 && !n[index].Active)){
list += '<option value=' + n[index].Id + ' data-active='+n[index].Active+'>' + n[index].Name + '</option>';
}
}
$this.filter("select").each(function () {
$(this).empty();
$(this).append(list);
if ($.ui.selectmenu && defaults.selectmenu) {
$this.selectmenu();
}
});
}
$.fn.ajaxSelect = function (options) {
var $this = this;
//options
var settings = $.extend({}, defaults, options);
//disable select
if ($.ui.selectmenu && settings.selectmenu && settings.disableOnLoad) {
$this.selectmenu('disable');
}
//ajax call
$.ajax({
type: settings.type,
contentType: settings.contentType,
url: settings.url,
dataType: settings.dataType,
data: settings.data
}).done(function (data) {
meinData = data.d || data;
$($this).createOptions(-1)
settings.success.call(this);
}).fail(function () {
settings.error.call(this);
});
return this;
};
var defaults = {
type: "POST",
contentType: "application/json; charset=utf-8",
url: '/echo/json/',
dataType: 'json',
data: null,
async: true,
selectmenu: true,
disableOnLoad: true,
success: function () {},
error: function () {}
};
})(jQuery);
$(function () {
var data = {
json: $.toJSON({
d: [{ "Id": 1, "Name": "Active One", "Active":true }, { "Id": 2, "Name": "Active Two", "Active":true },{ "Id": 3, "Name": "Unactive One", "Active":false }, { "Id": 4, "Name": "Unactive Two", "Active":false }]
}),
delay: 2//simulate loading
};
function ok() {
$('select#me').selectmenu({ select: function(event, options) {
$('select#mein').createOptions(options.value)
}
});
}
function error() {
alert('there was a problem :(');
}
$('select#me').selectmenu().selectmenu('disable');
$('select#mein').selectmenu().ajaxSelect({
data: data,
success: ok,
error: error
});
});

Categories

Resources