.ajax and params and how to get them to look like this? - javascript

I tried posting a previous question, but i believe it was convoluted.
Basically, i was told "can you make the data come thru like this?" - keep in mind that this data is not derived from a form, but but by data that is driven via a search on the client side.
This is what is suppose to be sent to the server. So if you dumped the error_log, it would look this. This is all dynamic, so the object below will be that format BUT the data will change.
{
"matchedItems" :
[
{ "itemID1" :
{ "Cost" : "12",
"Size" : "small",
"Colors" : [ "blue", "red" ]
}
},
{ "itemdID2" :
{ "Cost" : "33",
"Size" : "large",
"Colors" : [ "yellow" ]
}
}
]
}
so, I run thru the some things on the page and bundle up the data and return data sets, thus the hashes within the array.
BUT for the life of me, I can't get anything to look good in the actual .ajax post. When I console.log the data out, it looks good. Its an array of hashes. etc... looks fine. BUT the following is what is actually sent when I look at the params of the request. So below is what I am actually sending. It did some weird merging and such, it looks like.
{
'matchedItems[0][itemid1][Color]' => 'Blue',
'matchedItems[0][itemid1][Size]' => 'small',
'matchedItems[0][itemid1][Cost]' => '33.90',
'matchedItems[1][itemid2][Color][]' => ['Silver'],
'matchedItems[1][itemid2][Size]' => 'small',
'matchedItems[1][itemid2][Cost]' => '44',
'matchedItems[2][itemid3][Color][]' => ['blue','Red'],
'matchedItems[2][itemid3][Size]' => 'large',
'matchedItems[2][itemid3][Cost]' => '23'
};
I tried to $.params the data, no luck. I tried various data settings in dataType, no luck. I am at a loss on how to format the data I send that mimics what I posted first.
Any ideas?

You should json_encode() your output from PHP
Example:
<?php
$arr = array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5);
echo json_encode($arr);
?>
Output:
{"a":1,"b":2,"c":3,"d":4,"e":5}
You can use jQuery to decode the json you got back from the ajax reply:
var json_reply = jQuery.parseJSON('{"a":1,"b":2,"c":3,"d":4,"e":5}');
alert( json_reply.a ); // alerts "1"

Related

Iterating over nested data JS

I'm a little bit new to programming and very new to JS so I apologize for the beginner question.
I'm trying to iterate through this data and get each tracks name and artist but I'm having an issue. Currently I'm trying something like this.
If anybody has any insight or suggestions I would appreciate it greatly.
I'm using a rails backend with JS frontend. Thank you!
function selectTracks(){
fetch(BACKEND_URL)
.then(response => response.json())
.then(playlist => {
playlist.data.forEach(playlist => {
`<h4> ${playlist.attributes.track.name}</h4>
<h4>${playlist.attributes.track.artist}></h4> `
// let newPlaylist = new Playlist(playlist, playlist.attributes)
console.log(fetch)
// document.getElementById("playlist-container").innerHTML += newPlaylist.renderPlaylistCard();
debugger
}
)}
)
}
My serializer looks like this
{
data: [
{
id: "1",
type: "playlist",
attributes: {
name: "Country Songs",
id: 1,
track_id: 10,
track: {
id: 10,
name: "First Song",
artist: "Randy",
created_at: "2020-06-17T02:09:07.152Z",
updated_at: "2020-06-17T02:09:07.152Z"
}
},
relationships: {
track: {
data: {
id: "10",
type: "track"
}
}
}
}
]
}
You need to replace forEach with map. The 'forEachloop doesn't return anything. But themapmethod return an array. (An array of HTML elements in your case
fetch(BACKEND_URL)
.then(response => response.json())
.then(playlist => {
return playlist.data.map(playlist => {
`<h4> ${playlist.attributes.track.name}</h4>
<h4>${playlist.attributes.track.artist}></h4> `
// let newPlaylist = new Playlist(playlist, playlist.attributes)
console.log(fetch)
// document.getElementById("playlist-container").innerHTML += newPlaylist.renderPlaylistCard();
debugger
}
)}
)
Your code technically works assuming that the BACKEND_URL is correct and the json is valid. But, in its current state, it doesn't do anything with the data. If you output the h4 tags, for instance, you should see them written to the screen.
document.write(
`<h4> ${playlist.attributes.track.name}</h4>
<h4>${playlist.attributes.track.artist}</h4> `
)
Or alternatively you could log the values out to prove that you are processing the data correctly:
console.log(playlist.attributes.track.name, playlist.attributes.track.artist)
If not, the next thing to check is the validity of your json. I'm assuming that you copied your json from the browser which will strip some quotes for readability. View the source to ensure that the key names are correctly wrapped in quotes like this:
{
"data": [
{
"id": "1",
"type": "playlist",
"attributes": {
"name": "Country Songs",
...
If you are using ActiveModel Serializers, they should be formatted correctly.
If your json is valid and you can write the h4 tags to the page with the correct data in them, then the problem probably lies in your Playlist class.
Another handy tool for diagnosing fetch() problems is in Chrome Developer Tools. Go to the Network and click the XHR filter. This will allow you to inspect the fetch request and see if the response is valid and the data is what you expect. Other browsers have a similar feature.

Jquery Autocomplete showing an empty list

Edit 2 : even better, multiple values works
Actually, one simply has to give a "value" field that fills the box. No need for the "id/label" field, but value field is required. This is working :
foreach ($queries as $query)
{
$results[] = [
'zip' => $query->zip,
'value' => $query->commune,
'libelle' => $query->libelle,
'lieudit' => $query->lieudit
];
}
return Response::json($results);
Edit : here is the solution, thanks to Adyson's answer
The script should be json formatted and returning
An array of objects with label and value properties:
[ { label: "Choice1", value: "value1" }, ... ]
(jQuery API documentation)
So, modifying the PHP script like this will work :
foreach ($queries as $query)
{
$results[] = [
'id' => $query->zip,
'value' => $query->commune,
];
}
return Response::json($results);
Original question
Using Jquery Autocomplete, querying a script.
The list shows as many rows as there are results (when I set my script to return X results, there are X rows as well in the list) :
But it doesn't fill the rows with the data. What could have gone wrong there ?
The data returned is some json :
Request URL:http://localhost:8000/search/autocomplete?term=750
Request Method:GET
Status Code:200 OK
Remote Address:127.0.0.1:8000
Response Headers
view source
Cache-Control:no-cache
Connection:close
Content-Type:application/json
Date:Tue, 15 Nov 2016 14:53:07 GMT
Host:localhost:8000
And here is the data :
[{"zip":"75004","commune":"PARIS 04","libelle":"PARIS","lieudit":""},
{"zip":"75005","commune":"PARIS 05","libelle":"PARIS","lieudit":""},
{"zip":"75003","commune":"PARIS 03","libelle":"PARIS","lieudit":""},
{"zip":"75006","commune":"PARIS 06","libelle":"PARIS","lieudit":""},
{"zip":"75008","commune":"PARIS 08","libelle":"PARIS","lieudit":""},
{"zip":"75012","commune":"PARIS 12","libelle":"PARIS","lieudit":""},
{"zip":"75015","commune":"PARIS 15","libelle":"PARIS","lieudit":""},
{"zip":"75016","commune":"PARIS 16","libelle":"PARIS","lieudit":""},
{"zip":"75017","commune":"PARIS 17","libelle":"PARIS","lieudit":""},
{"zip":"75010","commune":"PARIS 10","libelle":"PARIS","lieudit":""},
{"zip":"75018","commune":"PARIS 18","libelle":"PARIS","lieudit":""},
{"zip":"75001","commune":"PARIS 01","libelle":"PARIS","lieudit":""},
{"zip":"75009","commune":"PARIS 09","libelle":"PARIS","lieudit":""},
{"zip":"75014","commune":"PARIS 14","libelle":"PARIS","lieudit":""},
{"zip":"75002","commune":"PARIS 02","libelle":"PARIS","lieudit":""},
{"zip":"75007","commune":"PARIS 07","libelle":"PARIS","lieudit":""},
{"zip":"75011","commune":"PARIS 11","libelle":"PARIS","lieudit":""},
{"zip":"75013","commune":"PARIS 13","libelle":"PARIS","lieudit":""},
{"zip":"75019","commune":"PARIS 19","libelle":"PARIS","lieudit":""},
{"zip":"75020","commune":"PARIS 20","libelle":"PARIS","lieudit":""}]
Here is my JS :
$(function(){
$( "#fromzip" ).autocomplete({
source: "/search/autocomplete",
dataType: 'json',
minLength: 3,
});
});
The HTML :
<input
id="fromzip"
name="fromzip"
type="text"
class="form-control"
placeholder="69003"
pattern=".{5}"
title="5 numbers zip"
maxlength="5"
required >
And the PHP (Laravel Input, DB and Response facades) :
public function autocomplete(){
$term = Input::get('term');
$results = array();
$queries = DB::table('zips')
->where('zip', 'LIKE', $term.'%')
->orWhere('libelle', 'LIKE', $term.'%')
->take(30)->get();
foreach ($queries as $query)
{
$results[] = [ 'zip' => $query->zip,
'commune' => $query->commune,
'libelle' => $query->libelle,
'lieudit' => $query->lieudit];
}
return Response::json($results);
}
Have a look at http://api.jqueryui.com/autocomplete/#option-source. It states that the data must be in the format
[ { label: "Choice1", value: "value1" }, ... ]
Your sample data items don't have either of those properties (label or value).
You can modify your server-side script to output the right format, or if you can't/won't do that, you could use the source-as-a-function option in the plugin to write a function that transforms the data.

MongoDB aggregation: How to extract the field in the results

all!
I'm new to MongoDB aggregation, after aggregating, I finally get the result:
"result" : [
{
"_id" : "531d84734031c76f06b853f0"
},
{
"_id" : "5316739f4031c76f06b85399"
},
{
"_id" : "53171a7f4031c76f06b853e5"
},
{
"_id" : "531687024031c76f06b853db"
},
{
"_id" : "5321135cf5fcb31a051e911a"
},
{
"_id" : "5315b2564031c76f06b8538f"
}
],
"ok" : 1
The data is just what I'm looking for, but I just want to make it one step further, I hope my data will be displayed like this:
"result" : [
"531d84734031c76f06b853f0",
"5316739f4031c76f06b85399",
"53171a7f4031c76f06b853e5",
"531687024031c76f06b853db",
"5321135cf5fcb31a051e911a",
"5315b2564031c76f06b8538f"
],
"ok" : 1
Yes, I just want to get all the unique id in a plain string array, is there anything I could do? Any help would be appreciated!
All MongoDB queries produce "key/value" pairs in the result document. All MongoDB content is basically a BSON document in this form, which is just "translated" back to native code form by the driver to the language it is implemented in.
So the aggregation framework alone is never going to produce a bare array of just the values as you want. But you can always just transform the array of results, as after all it is only an array
var result = db.collection.aggregate(pipeline);
var response = result.result.map(function(x) { return x._id } );
Also note that the default behavior in the shell and a preferred option is that the aggregation result is actually returned as a cursor from MongoDB 2.6 and onwards. Since this is in list form rather than as a distinct document you would process differently:
var response = db.collection.aggregate(pipeline).map(function(x) {
return x._id;
})

Ruby - parsing JSON coming via URL

I'm sending a JSON object to ruby with javascript. But I cannot parse it in there. I tried following stuff but no luck. Also I've been searching around for while now, but I couldn't find anything helpful.
Note that I'm very new ruby.
My trials:
def initialize(game_conf_json)
parsed_conf = JSON.parse(conf_json)
#param1 = parsed_conf['name'][0]
#param2 = parsed_conf['surname'][0]
=begin
I also tried this:
#param1 = parsed_conf['name']
#param2 = parsed_conf['surname']
But no matter what other things I try, I'm getting the following error:
"21:in `[]': can't convert String into Integer (TypeError)"
OR
"can't convert Array into String (TypeError), "
=end
File.open("some_direc/conf.json", "w") do |f|
f.write(game_conf_json)
end
end
I create the json in javascript like this:
var json_of_form_vars = {};
json_of_form_vars.name = name_val;
json_of_form_vars.surname = surname_val;
And send it this way:
$.ajax({
url: "../fundament/dispatch.rb/",
type: "post",
dataType: "json",
data: "conf="+json_of_form_vars,
.....
How can I solve this problem? Is there any proper tutorial for this of problem?
UPDATE1 (After suggestions):
I used JSON.stringify and then passed the object to ruby. And then I finally able to print the object in ruby. It's listed below:
{"name": "METIN", "surname": "EMENULLAHI"}
The method .class claims that it is an array. But I cannot access data with classical ways, like:
array['name']
the error is:
can't convert String into Integer
And when I try to pass it to the JSON.parse in ruby, it gives me the following error:
can't convert Array into String
So I used JSON.parse(conf_array.to_json), but again when accessing the data it gives the same error like arrays:
can't convert String into Integer
What should be done now?
UPDATE2
Here is my cgi handler which passes the URL parameters to appropriate places:
cgi_req = CGI::new
puts cgi_req.header
params_from_request = cgi_req.params
logger.error "#{params_from_request}"
action_todo = params_from_request['action'][0].chomp
base = Base.new
if action_todo.eql?('create')
conf_json = params_from_request['conf']
# This line prints the json like this: {"name": "SOME_NAME", "surname": "SOME_SURNAME"}
logger.error "#{conf_json}"
base.create_ident(conf_json)
end
And in Base class:
def create_ident(conf_json)
require 'src/IdentityCreation'
iden_create = IdentityCreation.new(conf_json)
end
IdentityCreation's constructor is listed above.
UPDATE3:
Ok, I now get at least something out of the array. But when I access a key, it displays the key itself:
parsed_conf = JSON.parse(conf_json.to_json)
#param1 = parsed_conf[0]['name']
#param2 = parsed_conf[0]['surname']
# At this point when I print the #param1, it gives me "name"(the key), not "SOME_NAME"(the value).
Here an example of parsing a JSON string. If you still have problems, publish the generated JSON so that we can try it.
require 'json'
require 'ap'
string = %{
{"configurations" : [
{ "drinks" : [
{"menus" : [
{ "hot" : [
{"id":15,"unit":"0.33", "price":"1", "currency":"Euro", "position": 4},
{"id":15,"unit":"0.33", "price":"1", "currency":"Euro", "position": 6}
] },
{ "cold" : [
{"id":15,"unit":"0.33", "price":"1", "currency":"Euro", "position": 4},
{"id":15,"unit":"0.33", "price":"1", "currency":"Euro", "position": 6}
] },
{ "terminals" : { "id" : 4, "id": 6, "id": 7 } },
{ "keys" : { "debit" : "on", "credit": "off" } }
] }
] } ] }
}
hash = JSON.parse(string)
ap hash
gives
{
"configurations" => [
[0] {
"drinks" => [
[0] {
"menus" => [
[0] {
"hot" => [
[0] {
"id" => 15,
"unit" => "0.33",
"price" => "1",
"currency" => "Euro",
"position" => 4
},
etc..
At the moment you're not actually posting json. You're attemping to post json wrapped inside form encoded parameters. In addition, when you do
"conf=" + json_of_form_vars
javascript will convert json_of_form_vars to a string for you but that conversion isn't the same as dumping to JSON. Javascript default string conversions are pretty useless for objects, so you'll need to use JSON.stringify to get actual json.
Since you're composing the body as a string literal you'll also need to escape any special characters that aren't allowed (or have special meaning) in this context. It's usually easier to let jquery do the heavy lifting, with something like
$.ajax({
url: "../fundament/dispatch.rb/",
type: "post",
dataType: "json",
data: {conf: JSON.stringify(json_of_form_vars)}
I solved it finally. Using all the suggestions made under this post and also my irb experiences with hashes, arrays, json and etc.
So instead of converting my object (conf_json) to json (with to_json), I passed it to JSON.parse as a string like below:
parsed_conf = JSON.parse(%{#{conf_json}})
It seems kind of weird to me, because when try to pass it to function like below, I got the error of can't convert Array into String.
parsed_conf = JSON.parse(conf_json)
But it is working like a charm right now.

How do I store an array of objects in a cookie with jQuery $.cookie()?

I have a list of javascript objects:
var people = [
{ 'name' : 'Abel', 'age' : 1 },
{ 'name' : 'Bella', 'age' : 2 },
{ 'name' : 'Chad', 'age' : 3 },
]
I tried to store them in a browser cookie with jQuery $.cookie():
$.cookie("people", people);
I then retrieve this cookie and then try to push another object into it:
var people = $.cookie("people");
people.push(
{ 'name' : 'Daniel', 'age' : 4 }
);
However, this does not work; I analyzed this code in Firebug, and Console noted that people was a string ("[object Object],[object Object],[object Object]") and that the push function did not exist.
What is going on? What is the proper way to store and retrieve a list of objects?
Cookies can only store strings. Therefore, you need to convert your array of objects into a JSON string. If you have the JSON library, you can simply use JSON.stringify(people) and store that in the cookie, then use $.parseJSON(people) to un-stringify it.
In the end, your code would look like:
var people = [
{ 'name' : 'Abel', 'age' : 1 },
{ 'name' : 'Bella', 'age' : 2 },
{ 'name' : 'Chad', 'age' : 3 },
];
$.cookie("people", JSON.stringify(people));
// later on...
var people = $.parseJSON($.cookie("people"));
people.push(
{ 'name' : 'Daniel', 'age' : 4 }
);
$.cookie("people", JSON.stringify(people));
I attempted this today and could not get it to work. Later i found out that it was because I had 3 very large objects which I tried to save in a cookie.
The way I worked arround this was by storing the information in the browsers local storage.
example:
localStorage.setItem("test2", JSON.stringify(obj) )
localStorage.getItem("test2")
further info about local storage: cookies vs local storage
4 hours of my time vent to this, dont make the same mistake.

Categories