Pass Javascript nested array to PHP using Ajax in external Javascript file - javascript

I want to pass a nested javascript array that is dynamically generated to a php file to later insert it into the database.
The array is dynamically generated inside a Javascript file. Now i want to pass that array to a php file that will insert that data dynamically into a database.
I have found multiple examples of this question on stackoverflow but none suit my situation (they are all working from inside an HTML file).
The array I am trying to pass:
1. 0:
1. cleintDate:"31/08/17"
2. cleintExpirydate:"29/11/17"
3. cleintState:"Department"
4. clientCode:"clientcode"
5. clientName:"Name"
6. messages:Array(2)
1. 0:
1. messageClient:"Name"
2. messageDate:"2017-08-31T00:00:00"
3. messageSubject:"subject "
4. messageText:"messageText "
5. messageTime:"13:22"
6. messageType:"link"
7. __proto__:Object
2. 1:
1. messageClient:"Name"
2. messageDate:"2017-08-31T00:00:00"
3. messageSubject:"subject "
4. messageText:"messageText "
5. messageTime:"13:22"
6. messageType:"link"
7. __proto__:Object
3. length:2
**Note:**The above example contains 2 messages inside the array but there are examples of 54 messages inside the array. (Text of array slightly edited to hide personal information).
How I generate this array:
matches[0].forEach(function(match, index) {
var cleintcode = /<div\s*class="t_seg_codCliente">(.*?)<\/div>/.exec(match)[1];
var cleintname = /<div\s*class="t_seg_nomCliente">(.*?)<\/div>/.exec(match)[1];
var taxId = /<div\s*class="t_seg_nifCliente">(.*?)<\/div>/.exec(match)[1];
var date = /<div\s*class="t_seg_fechaPresCliente">(.*?)<\/div>/.exec(match)[1];
var state = /<div\s*class="t_seg_estadoCliente">(.*?)<\/div>/.exec(match)[1];
var expirydate = /<div\s*class="t_seg_fechaCadCliente">(.*?)<\/div>/.exec(match)[1];
var communications = /<div\s*class="t_seg_comCliente"><a .*;">(.*?)<\/a>/.exec(match)[1];
var comclient = /<div\s*class="t_seg_comCliente"><a href="javaScript:popupComs\('(.*?)'/.exec(match)[1];
var messages = "link" + comclient;
var html1 = httpGet(messages);
const cleanupDocString = html1.replace(/(?:<!--|-->)/gm, '');
parser = new DOMParser();
htmlDoc = parser.parseFromString(cleanupDocString, "text/html");
var communicationsvalue = htmlDoc.getElementsByClassName("valorCampoSinTamFijoPeque")[0].textContent;
if (communicationsvalue.indexOf('No existen comunicaciones asociadas a este cliente.') !== -1) {
console.log("This chat does not contain any communiction!");
} else {
var adiv = document.createElement("div"),
msgs = [],
trs;
adiv.innerHTML = cleanupDocString;
trs = adiv.querySelectorAll('tr[bgcolor="#FFFFFF"]');
trs.forEach(function(tr) {
var d = [];
tr.querySelectorAll("td")
.forEach(function(td) {
var img = td.querySelector("img"),
src = img && img.attributes.getNamedItem("src").value;
d.push(src || td.textContent);
});
msgs.push(d);
});
var mappedArray = msgs.map((msg) => {
return {
messageDate: msg[0],
messageTime: msg[1],
messageType: msg[2],
messageClient: msg[3],
messageSubject: msg[4],
messageText: msg[5]
}
});
var messageData = [{
clientCode: cleintcode,
clientName: cleintname,
taxID: taxId,
cleintDate: date,
cleintState: state,
cleintExpirydate: expirydate,
messages: mappedArray
}];
console.log(messageData);
}
});
The code I am trying to use to pass the array:
$.ajax({
type: "POST",
url: "../php/messageProcessing.php",
data: {
"id": 1,
"myJSArray": JSON.stringify(messageData)
},
success: function(data) {
alert(data);
}
});
The error it gives me:
Uncaught ReferenceError: $ is not defined
at ProcessAJAXRequest (getPagesSource.js:126)
at getPagesSource.js:139
at Array.forEach (<anonymous>)
at DOMtoString (getPagesSource.js:62)
at getPagesSource.js:150
Summary:
How do i pass a Javascript array with Ajax (or any other solution) from a external Javascript file.
And how do I dynamically get each piece of data from messages to insert into the Database.
Thanks for any piece of help!

The problem seems to be that you have used JQuery without including the JQuery library on the page. The JQuery library exposes a global variable $ and must be loaded into the global context before being used by other javascript files.
$.ajax({
type: "POST",
url: "../php/messageProcessing.php",
data: {
"id": 1,
"myJSArray": JSON.stringify(messageData)
},
success: function(data) {
alert(data);
}
});
You can fix this by including jQuery somewhere in the page from the cdn (lastest version):
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
Alternatively, if you were not intending to use a JavaScript library, you will have to look into how to use XmlHttpRequest to do what you are looking for. This is built into the javascript language itself.
how do I dynamically get each piece of data from messages to insert
into the Database?
You will receive a POST request in the PHP script with the myJSArray in the body. You will be able to access it via $_POST['myJSArray'], you will then need to parse it as JSON and then treat is as any other kind of PHP object.

Related

How can I assign dictionary values to javascript variables (jQuery / AJAX API call returned in JSON)

I have a well running AJAX request that queries data from a third party API that returns the data in JSON. I now want to assign the values from the returned JSON data to javascript variables to make further manipulation to the data itself in my AJAX success function before updating the frontend.
In the below example I would like to assign the value of key name to my Javascript team variable.
What would be the best way to accomplish this?
This is the returned structure:
{
"api":{
"results":1,
"teams":[
{
"team_id":66,
"name":"Barcelona",
"code":null,
"logo":"Not available in Demo",
"country":"Spain",
"founded":1899,
"venue_name":"Camp Nou",
"venue_surface":"grass",
"venue_address":"Carrer d&apos;Ar\u00edstides Maillol",
"venue_city":"Barcelona",
"venue_capacity":99787
}
],
This is my AJAX request:
$('ul.subbar li a').on('click', function(e) {
e.preventDefault();
var team_id = $(this).attr("id");
console.log(team_id);
$.ajax({
method: "GET",
dataType: "json",
url: "https://cors-anywhere.herokuapp.com/http://www.api-football.com/demo/api/v2/teams/team/" + team_id,
success: function(response) {
var team_data = response
console.log(team_data)
team = // how to assign team name from API callback to variable
console.log(team)
$("#selectedClub").html(response);
}
});
});
You can use dot notation to navigate through objects
team_data.api.teams[0].name //output: "barcelona"
In you example there is only one item inside teams array, so the above example should works fine, but let's suppose that in your response there is more than 1 team on teams then you could do something like this:
var teamList = [];
$.each(team_data.api.teams, function(index, team){
teamList.push(team.name);
})
and it will give an array with all team names from your ajax response
put JSON in js obj variable
var obj = JSON.parse('{ <key:value>,<key:value>...}');
Make sure the text is written in JSON format, or else you will get a syntax error.
Use the JavaScript object in your page:
Example
<p id="demo"></p>
<script>
document.getElementById("name").innerHTML = obj.name + ", " + obj.country;
</script>

Use JSON output from Flickr to display images from search

I need to display the images on my site from a JSON request.
I have the JSON:
https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=6a970fbb976a06193676f88ef2722cc8&text=sampletext&sort=relevance&privacy_filter=1&safe_search=1&per_page=5&page=1&format=json&nojsoncallback=1
And I have the format I need to put the photo URL in:
https://www.flickr.com/services/api/misc.urls.html
But I don't know how I would loop through that, I found some examples similar, but I am still having trouble seeing what I need.
I am using JavaScript/jQuery to pull the info.
I figure I would have this in a loop.
CurrentPhotoUrl = 'https://farm'+CurrentPhotoFarm+'.staticflickr.com/'+CurrentPhotoServer+'/'+CurrentPhotoId+'_'+CurrentPhotoSecret+'_n.jpg'
But each of those variables would need to be populated with an value from the element. I would need to loop through all 5 elements that are in the JSON.
Any help on how to create this loop would be greatly appreciated.
Try this code
var n = JSON.parse(x) //x is the json returned from the url.
var _s = n.photos.photo;
for(var z = 0 ; z < n.photos.photo.length ; z++)
{
var CurrentPhotoUrl = 'https://farm'+_s[z]['farm']+'.staticflickr.com/'+_s[z]['server']+'/'+_s[z]['id']+'_'+_s[z]['secret']+'_n.jpg'
console.log(CurrentPhotoUrl);
}
Edit ( With actual JQUERY AJAX call )
var n ='';
$.ajax({url: "https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=6a970fbb976a06193676f88ef2722cc8&text=sampletext&sort=relevance&privacy_filter=1&safe_search=1&per_page=5&page=1&format=json&nojsoncallback=1", success: function(result){
console.log(result);
n = result;
var _s = n.photos.photo;
for(var z = 0 ; z < n.photos.photo.length ; z++)
{
var CurrentPhotoUrl = 'https://farm'+_s[z]['farm']+'.staticflickr.com/'+_s[z]['server']+'/'+_s[z]['id']+'_'+_s[z]['secret']+'_n.jpg'
console.log(CurrentPhotoUrl);
}
}});
Output:
https://farm8.staticflickr.com/7198/6847644027_ed69abc879_n.jpg
https://farm3.staticflickr.com/2517/3905485164_84cb437a29_n.jpg
https://farm1.staticflickr.com/292/32625991395_58d1f16cea_n.jpg
https://farm9.staticflickr.com/8181/7909857670_a64e1dd2b2_n.jpg
https://farm9.staticflickr.com/8143/7682898986_ec78701508_n.jpg
This answer assumes your json data will not change. So inside a .js file, set your json to a variable.
var json = <paste json here>;
// the photos are inside an array, so use forEach to iterate through them
json.photos.photo.forEach((photoObj) => {
// the photo will render via an img dom node
var img = document.createElement('img');
var farmId = photoObj.farm;
// you can fill out the rest of the variables ${} in the url
// using the farm-id as an example
img.src = `https://farm${farmId}.staticflickr.com/${serverId}/${id}_${secret}.jpg`
// add the image to the dom
document.body.appendChild(img);
}
Inside your html file that contains a basic html template, load this javascript file via a script tag, or just paste it inside a script tag.
If you want to get the json from the web page and assuming you have the jquery script loaded...
$.ajax({
type: 'GET',
url: <flicker_url_for_json>,
success: (response) => {
// iterate through json here
},
error: (error) => {
console.log(error);
}
});
I'm not sure if this is the best solution but its is something someone suggested and it worked.
const requestURL = 'https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=6a970fbb976a06193676f88ef2722cc8&text=sampletext&sort=relevance&privacy_filter=1&safe_search=1&per_page=5&page=1&format=json&nojsoncallback=1'
$.ajax(requestURL)
.done(function (data) {
data.photos.photo.forEach(function (currentPhoto) {
console.log('https://farm'+currentPhoto.farm+'.staticflickr.com/'+currentPhoto.server+'/'+currentPhoto.id+'_'+currentPhoto.secret+'_n.jpg')
})
})
Varun's solution worked for me as well. I don't know which one is better but I thought I would post this as well since it looks like they were done fairly differently.

Javascript loading CSV file into an array

I am developing a web page in Wordpress. The webpage needs to have a combobox with all counties. I have a dataset in csv format which has some 10k rows for all these counties.
When the user selects a county in the dropdown, I want only the selected county data displayed in the web page. This is my requirement.
In wordpress, my web page I am adding the js file using
<script type="text/javascript" src="http://xxx/wp content/uploads/2014/05/countyList1.js"></script>
and the code for webpage dropdown is
<select name="county" id="county" onload="setCounties();" onchange="getSelectedCountyData();"></select>
In countyList1.js file I have the setCounties() and getSelectedCountyData() functions.
So far I can see the dropdown with counties list. I don't know how to read the CSV file and apply the selected county filter to this list.
I tried the FileReader object and I can load the CSV contents on the web page but I don't want the user to select the CSV. I have the dataset already.
I am trying to use this jquery.csv-0.71 library from this SO post How to read data From *.CSV file using javascript? but I need help.
Here's the code which gets called when a county is selected
function getSelectedCountyData() {
cntrySel = document.getElementById('county');
//selCty = countyList[cntrySel.value];
handleFiles();
}
function handleFiles() {
$(document).ready(function () {
$.ajax({
type: "GET",
url: "D:\Docs\Desktop\csvfile.csv",
dataType: "csv",
success: function (data) { processData(data); }
});
});
}
function processData(allText) {
var allTextLines = allText.split(/\r\n|\n/);
var headers = allTextLines[0].split(',');
var lines = [];
for (var i = 1; i < allTextLines.length; i++) {
var data = allTextLines[i].split(',');
if (data.length == headers.length) {
var tarr = [];
for (var j = 0; j < headers.length; j++) {
tarr.push(headers[j] + ":" + data[j]);
}
lines.push(tarr);
}
}
console.log(lines);
drawOutput(lines);
}
function drawOutput(lines) {
//Clear previous data
document.getElementById("output").innerHTML = "";
var table = document.createElement("table");
for (var i = 0; i < lines.length; i++) {
var row = table.insertRow(-1);
for (var j = 0; j < lines[i].length; j++) {
var firstNameCell = row.insertCell(-1);
firstNameCell.appendChild(document.createTextNode(lines[i][j]));
}
}
document.getElementById("output").appendChild(table);
}
I highly recommend looking into this plugin:
http://github.com/evanplaice/jquery-csv/
I used this for a project handling large CSV files and it handles parsing a CSV into an array quite well. You can use this to call a local file that you specify in your code, also, so you are not dependent on a file upload.
Once you include the plugin above, you can essentially parse the CSV using the following:
$.ajax({
url: "pathto/filename.csv",
async: false,
success: function (csvd) {
data = $.csv.toArrays(csvd);
},
dataType: "text",
complete: function () {
// call a function on complete
}
});
Everything will then live in the array data for you to manipulate as you need. I can provide further examples for handling the array data if you need.
There are a lot of great examples available on the plugin page to do a variety of things, too.
You can't use AJAX to fetch files from the user machine. This is absolutely the wrong way to go about it.
Use the FileReader API:
<input type="file" id="file input">
js:
console.log(document.getElementById("file input").files); // list of File objects
var file = document.getElementById("file input").files[0];
var reader = new FileReader();
content = reader.readAsText(file);
console.log(content);
Then parse content as CSV. Keep in mind that your parser currently does not deal with escaped values in CSV like: value1,value2,"value 3","value ""4"""
If your not overly worried about the size of the file then it may be easier for you to store the data as a JS object in another file and import it in your . Either synchronously or asynchronously using the syntax <script src="countries.js" async></script>. Saves on you needing to import the file and parse it.
However, i can see why you wouldnt want to rewrite 10000 entries so here's a basic object orientated csv parser i wrote.
function requestCSV(f,c){return new CSVAJAX(f,c);};
function CSVAJAX(filepath,callback)
{
this.request = new XMLHttpRequest();
this.request.timeout = 10000;
this.request.open("GET", filepath, true);
this.request.parent = this;
this.callback = callback;
this.request.onload = function()
{
var d = this.response.split('\n'); /*1st separator*/
var i = d.length;
while(i--)
{
if(d[i] !== "")
d[i] = d[i].split(','); /*2nd separator*/
else
d.splice(i,1);
}
this.parent.response = d;
if(typeof this.parent.callback !== "undefined")
this.parent.callback(d);
};
this.request.send();
};
Which can be used like this;
var foo = requestCSV("csvfile.csv",drawlines(lines));
The first parameter is the file, relative to the position of your html file in this case.
The second parameter is an optional callback function the runs when the file has been completely loaded.
If your file has non-separating commmas then it wont get on with this, as it just creates 2d arrays by chopping at returns and commas. You might want to look into regexp if you need that functionality.
//THIS works
"1234","ABCD" \n
"!#£$" \n
//Gives you
[
[
1234,
'ABCD'
],
[
'!#£$'
]
]
//This DOESN'T!
"12,34","AB,CD" \n
"!#,£$" \n
//Gives you
[
[
'"12',
'34"',
'"AB',
'CD'
]
[
'"!#',
'£$'
]
]
If your not used to the OO methods; they create a new object (like a number, string, array) with their own local functions and variables via a 'constructor' function. Very handy in certain situations. This function could be used to load 10 different files with different callbacks all at the same time(depending on your level of csv love! )
This is what I used to use a csv file into an array. Couldn't get the above answers to work, but this worked for me.
$(document).ready(function() {
"use strict";
$.ajax({
type: "GET",
url: "../files/icd10List.csv",
dataType: "text",
success: function(data) {processData(data);}
});
});
function processData(icd10Codes) {
"use strict";
var input = $.csv.toArrays(icd10Codes);
$("#test").append(input);
}
Used the jQuery-CSV Plug-in linked above.
The original code works fine for reading and separating the csv file data but you need to change the data type from csv to text.

fetch json object containing 3 arrays with ajax call and pass arrays to javascript

I have a page that creates the following output:
<script>
var JSONObject = { "groups":['1210103','1210103','1210103','1210405'],
"prices":['279,00','399,00','628,00','129,00'],
"titles":['','','','']
};
</script>
This page is called by an ajax call:
$.ajax({url:plink,success: function(result) { }
I now need to recieve the json arrays and pass them to ordinary javascript arrays.
How do I do that?
I have tried with:
result = jQuery.parseJSON(data);
mygroups = result.groups;
myprices = result.prices;
mylabels = result.titles;
Change your page so that it just produces JSON:
{"groups":["1210103","1210103","1210103","1210405"],
"prices":["279,00","399,00","628,00","129,00"],
"titles":["","","",""]
}
Note that in JSON, you must use ", not ', for quoting strings.
Have it return a Content-Type header of application/json. If for some reason you can't set the correct Content-Type header on the response, you can force jQuery to treat the response as JSON by adding dataType: 'json' to your ajax call, but it's best to use the correct content-Type.
Then in your ajax call's success callback, result will already be a deserialized object with three properties (groups, prices, titles), which will be JavaScript arrays you can work with.
Live Example | Source
You've said in the comments below that the page is a full HTML page with the embedded script tag and you have no control over it other than the contents of the script tag, because of the CMS you're using.
I strongly suggest moving to a more flexible CMS.
Until/unless you can do that, you can simply receive the page as text and then extract the JSON. Change your script tag to something like this:
<script>
var JSONObject = /*XXX_JSONSTART_XXX*/{"groups":["1210103","1210103","1210103","1210405"],
"prices":["279,00","399,00","628,00","129,00"],
"titles":["","","",""]
}/*XXX_JSONEND_XXX*/;
</script>
Note the markers. Then you can extract the JSON between the markers, and use $.parseJSON on it. Example:
(function($) {
$.ajax({
url: "http://jsbin.com/ecolok/1",
dataType: "text",
success: function(result) {
var startMarker = "/*XXX_JSONSTART_XXX*/";
var endMarker = "/*XXX_JSONEND_XXX*/";
var start, end;
start = result.indexOf(startMarker);
if (start === -1) {
display("Start marker missing");
}
else {
start += startMarker.length;
end = result.indexOf(endMarker, start);
if (end === -1) {
display("End marker missing");
}
else {
result = $.parseJSON(result.substring(start, end));
display("result.groups.length = " + result.groups.length);
display("result.prices.length = " + result.prices.length);
display("result.titles.length = " + result.titles.length);
}
}
}
});
function display(msg) {
$("<p>").html(String(msg)).appendTo(document.body);
}
})(jQuery);
Live Copy | Source

Javascript - Trouble using for...in to iterate through an object

I have a dynamically-generated object that looks like this:
colorArray = {
AR: "#8BBDE1",
AU: "#135D9E",
AT: "#8BBDE1",
... }
I'm trying to use it to color a map by using this plugin and the 'colors' attribute during the call to the plugin. Like this:
$('#iniDensityMap').vectorMap({
backgroundColor: '#c2e2f2',
colors: colorArray,
... (some other params)
});
But it doesn't color in the countries. When I hard code this in, it works fine - but it must be dynamically generated for this project, so something like this won't work for me (although it does in fact color the map):
$('#iniDensityMap').vectorMap({
backgroundColor: '#c2e2f2',
colors: { AR: "#8BBDE1", AU: "#135D9E", AT: "#8BBDE1" },
... (some other params)
});
I've traced the issue far enough into the plugin to find it has something to do with this loop:
setColors: function(key, color) {
if (typeof key == 'string') {
this.countries[key].setFill(color);
} else {
var colors = key; //This is the parameter passed through to the plugin
for (var code in colors) {
//THIS WILL NOT GET CALLED
if (this.countries[code]) {
this.countries[code].setFill(colors[code]);
}
}
}
},
I've also tried iterating through the colorArray object on my own, outside of the plugin and I'm running into the same issue. Whatever sits inside the for ( var x in obj ) isn't firing. I've also noticed that colorArray.length returns undefined. Another important note is that I've instantiated var colorArray = {}; in a separate call, attempting to ensure that it is sitting at the global scope and able to be manipulated.
I'm thinking that the problem is either:
The way I'm dynamically populating the object - colorArray[cCode] =
cColor; (in a jQuery .each call)
I'm once again confusing the differences between Arrays() and Objects() in javascript
It is a scope issue perhaps?
Some combination of everything above.
EDIT #1: I've moved my additional question about Objects in the Console in Firebug to a new post HERE. That question deals more specifically with Firebug than the underlying JS problem I'm asking about here.
Edit #2: Additional info
Here's the code I'm using to dynamically populate the Object:
function parseDensityMapXML() {
$.ajax({
type: "GET",
url: "media/XML/mapCountryData.xml",
dataType: "xml",
success: function (xml) {
$(xml).find("Country").each(function () {
var cName = $(this).find("Name").text();
var cIniCount = $(this).find("InitiativeCount").text();
var cUrl = $(this).find("SearchURL").text();
var cCode = $(this).find("CountryCode").text();
//Populate the JS Object
iniDensityData[cCode] = { "initiatives": cIniCount, "url": cUrl, "name": cName };
//set colors according to values of initiatives count
colorArray[cCode] = getCountryColor(cIniCount);
});
}
});
} //end function parseDensityMapXML();
This function is then called on a click event of a checkbox elsewhere on the page. The Objects iniDensityData and colorArray are declared in the head of the html file - hoping that keeps them in global scope:
<script type="text/javascript">
//Initialize a bunch of variables in the global scope
iniDensityData = {};
colorArray = {};
</script>
And finally, here's a snippet from the XML file that is being read:
<?xml version="1.0" encoding="utf-8"?>
<icapCountryData>
<Country>
<Name>Albania</Name>
<CountryCode>AL</CountryCode>
<InitiativeCount>7</InitiativeCount>
<SearchURL>~/advance_search.aspx?search=6</SearchURL>
</Country>
<Country>
<Name>Argentina</Name>
<CountryCode>AR</CountryCode>
<InitiativeCount>15</InitiativeCount>
<SearchURL>~/advance_search.aspx?search=11</SearchURL>
</Country>
... and so on ...
</icapCountryData>
Solved it! Originally, I was calling the function parseDensityMapXML() and then immediately after it calling another function loadDensityMapXML() which took the object created dynamically in the first function and iterated through it. Problem was, it wasn't called as a callback from the first function, so was firing before the Object had even been built.
To fix, I just amended the first function mentioned above to call the second function after the .each() was finished creating the objects:
function parseDensityMapXML() {
$.ajax({
type: "GET",
url: "media/XML/mapCountryData.xml",
dataType: "xml",
success: function (xml) {
$(xml).find("Country").each(function () {
var cName = $(this).find("Name").text();
var cIniCount = $(this).find("InitiativeCount").text();
var cUrl = $(this).find("SearchURL").text();
var cCode = $(this).find("CountryCode").text();
//Populate the JS Object
iniDensityData[cCode] = { "initiatives": cIniCount, "url": cUrl, "name": cName };
//set colors according to values of initiatives count
colorArray[cCode] = getCountryColor(cIniCount);
});
/* and then call the jVectorMap plugin - this MUST be done as a callback
after the above parsing. If called separately, it will fire before the
objects iniDensityData and colorArray are created! */
loadDensityMapXML();
}
});
} //end function parseDensityMapXML();

Categories

Resources