Sending JSON data to a client? D3.js rendering JSON data - javascript

I have a website with a form (currently it's plain HTML but we're switching to JQuery). The flow is like this :
Take in the user's inputs --- 5 integers
Make a call to a web service via REST
Run some calculations server side... and generate a JSON object
??? Now I have my result JSON object, but how do I get it to the client? Persist it?
??? Does the URL need to be the exact location of the JSON file? That would mean 100's
??? of JSON files in my web server's DIR.
D3.js on the client side, waits for the data to be present (via AJAX?).
var data; // a global
d3.json("path/to/file.json", function(error, json) {
if (error) return console.warn(error);
data = json;
visualizeit();
});
Once data is present, render for the client, and remove the calculator from the screen.
I'm having a tough time here, because I notice all AJAX requests need a URL.. but then does that mean I need to give a unique URL to each resulting JSON object? Doesn't that mean I need to persist that object?
I'd just like to have d3.js render my JSON object but unclear what are my options for where to put it.

How do I post parameter on d3.json?
Typically, you will pass some parameters via a javascript object or
a query parameter.
Basically, something like...
data = {}
data.var1 =5;
data.var2 =10;
var my_request = d3.xhr(url)
my_request.post(JSON.stringify(data), function(error,received)){
};
Or
d3.json(url+"?"+"var1=5&var2=10",function(error,received)){
}
Obviously, these form parameters can be parsed on the server easily. After the values are parsed on sever, the server can generate the new JSON using the form parameters that have been parsed.
Make sure that if you are running the script from a local page (or a page that is not on the website) that the server has the ability to allow cross origin (or domain) requests.
If you want to persist the data across multiple calls, you will probably have to to embed the callbacks, or use global variables.

Related

Get the js script from a rest api hit and execute it on browser

I need to get user details behind the scene when he is accessing our browser based application. So a plug and play JavaScript component need to be created which can be easily embedded in the header of the web page. The logic of capturing the data points should sit on server side. So an API can be invoked from this component and then "User-Agent" header can be leveraged in that API to get the data points.
However, not all data points can be Identified from User-Agent such as language, screen resolution, color depth, etc. Capturing these attributes need an execution of JavaScript on client side.
Two approaches:
With Redirect(If allowed and component is an iFrame so that parent page is not reloaded)
When the component loads initially, redirect it to another page which will contain the JavaScript that will capture these details and it will be auto submitted and sent to the API which will use the data points and then redirect to the component with a flag to not perform the capture activity again.
Without redirect
So, The approach am thinking is to have a component in which, during onLoad event, an API will be invoked and the JavaScript code (To capture the data points from client) will be returned as response. Then this returned JavaScript will be executed on client and result will be saved in a hidden field. There will be an Allow button(part of requirement to take user consent) in this component, which when clicked, the data from the hidden field will be submitted to the API.
Please review the approach and let me know if it sounds good and viable.
I bet that the second approach would be better. And even better, you don't actually need to write a dedicated API to generate the JS file s required for tracking.
Now, write a simple JavaScript file which will collect the required data. I'll name this as track.js.
function collectAndSubmit(){
var data = {};
// Then collect the required data
data.screenWidth = window.innerWidth;
data.screenHeight = window.innerHeight;
data.preferredLanguages = navigator.languages; // In the form of an array
// Submit the data through XHR
var xhr = new XMLHttpRequest();
xhr.open("POST", "https://example.com/track.php");
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); // Note that we're sending a JSON request
xhr.send(JSON.stringify(data));
}
The last 6 lines of code will send all of the collected data in JSON format to a server. However, I don't know which server are you using (e.g. PHP, Node.js) since they have different ways to parse the JSON data. For example, PHP you can use $data = json_decode(file_get_contents('php://input')); to obtain the requested data or var data = req.body; if you're using Node.js with Express and the body-parser module.
The best part here is that track.js doesn't have to be generated by an api, e.g. by performing a GET request to /gettrackingscript. Instead, you can serve this as a static file, putting it on your CDN and so on.
And now, what is the best way to download this track.js file? Well, it depends on how would you use it. You can simply include a <script src="track.js"> tag when the page loads and call the collectAndSubmit() method when you would like to send the data. Or by getting the script through another XMLHttpRequest and execute them with eval().
Since you're planning to redirect the user after all of the data has been sent, you don't have to refresh the page unless if you're sticking to the MVC (mode-view-controller) pattern when building the site. After the xhr.send(), you can set your backend server to send additional data back to the browser by sending a HTTP response, which you can parse it here by using:
xhr.onreadystatechange = function() {
if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
// Assuming that you're using JSON
var additionalData = JSON.parse(xhr.responseText);
}
}

Serve files from Apache to Javascript

I am writing my first web application with Javascript and WebGL. For now I am running the app on localhost from Apache. The app needs to work with data that is provided instantly. Until now I worked with AJAX calls that happen during runtime which doesn't work out for my purposes anymore. So instead of serving individual files from Server to Client when asked, I want the application to load all files from the Server to Client side at initialization time (I want this to happen automatically at the start so I don't have to add every new file as a url in the html index). I understand I should do this with Server Side scripting; probably with PHP since I have a Apache localhost? I have different folders which hold my necessary resources in a uniform dataformat (.txt, .png and .json). So what I want to do is, before the Javascript app starts, look through the folder and send one object per folder that holds filenames as keys bound to filedata. Is my intuition right that I need to do that with PHP? If yes, where do I start to tell my application what to do when (first start serving files with php, then start the javascript app)? How do I do this on localhost? Should I already think about extending my toolset (e.g. using nodeJS on ServerSide(locally for now))? If so what lightweight tools do you propose for this kind of work? I feel I am missing some design principles here.
EDIT:
Keep in mind that I don't want to specifically call a single file... I am already doing that. What I need is a script that automatically serves all the files of a certain folder on the server to the client side at init time of the app before the program logic of the actual application starts.
Your question is kind of broad so I'll try my best. Why does AJAX not work for real-time data but loading all the files once does? If you're working with real time data, why not look into a websocket or at the bare minimum, AJAX queries?
If you want to pass data from the server to the client, you will need to use a HTTP request no matter what. A GET request or POST request is necessary for the client to request data from the server and receive it as a response.
You could theoretically just pass the data from PHP straight to the view of the application (which is technically done through a GET request whenever a user requests data such as .php files from the server) but this isn't as flexible as if Javascript had access to the data. You can do some hacks and 'transfer' the data from the view to Javascript with some .value methods, but this isn't ideal and can be prone to some security holes. This also means data is only being passed once.
So what would need to happen is that the data would need to be processed upon initialization and then immediately transferred to the client by use of Javascript and HTTP requests.
So if you want Javascript to have access to the data and use it in variables or manipulate it further, then you'd need to use an HTTP request such as GET or POST which is called by Javascript. Otherwise, you need to immediately pass the data to the view upon initialization (through PHP), but this means you can't work with real-time data because the data is only being passed once when there is a page refresh.
Example of scandir():
<?php
//scandir() returns filenames, not data from files
$fileArray = scandir('datafolder/') //this is a relative path reference to the folder 'datafolder'
$finalArray = [];
foreach($fileArray as $filename){
tempArray = [];
$file = fopen('datafolder/' . $filename, 'r'); //im pretty sure scandir only retrieves the filenames and not the path, so you might need to append the filepath so your script knows where to look
$tempArray = fgetcsv($file, 1024); //temp array to hold contents of each iteration of foreach loop
array_push($finalArray, $tempArray); //this will store the data for later use
}
Or the data can be used however, depending on what it is. Say, if you need to combine the data from multiple .csv files, you can read each file and append it to a single array. If you want to read multiple distinct files and preserve the independence of each file, you can create multiple arrays and then pass back a single JSON encoded object that contains each file's data as a separate attribute of the object such as:
{
'dataOne': [0,1,2,3,4,5,6...],
'dataTwo': ['new', 'burger', 'milkshake'],
'dataThree': ['Mary', 'Joe', 'Pam', 'Eric']
}
Which can be created with a PHP associative array using one of the following methods:
//assuming $arrayOne is already assigned from reading a file and storing its contents within $arrayOne
$data['dataOne'] = $arrayOne;
// or
array_push($data['dataTwo'], $arrayTwo);
// or
array_push($data, [
'dataThree' => ['Mary', 'Joe', 'Pam', 'Eric']
]);
Then $data can simply be passed back which is a single array containing all the different sets of data, if each set needs to be distinct.

Write JSON data from front-end to back-end in nodejs

I have ButtonClick.js and TakeData.js files. I defined my json data in TakeData.js as below
var dataObj = {};
var locationsObj = "locations";
dataObj[locationsObj] = {};
dataObj[locationsObj].source = [];
dataObj[locationsObj].target = [];
When I click the button in ButtonClick.js and the code snippet as below
button()
.container(g2)
.text(text2)
.count(1)
.cb(function()
{
console.log(dataObj[locationsObj].source[0]);
console.log(dataObj[locationsObj].source[1]);
console.log(dataObj[locationsObj].target[0]);
console.log(dataObj[locationsObj].target[1]);
console.log("SaveFile");
})();
I want to send json data into the nodejs file writing function as the following.
fs.writeFile('sample.txt', [need to insert my JSON], function(err) {
if(err) return console.log(err);
console.log('Hello JSON > sample.txt');
});
How can I do that? Is there another effective way?
Your backend needs to have an HTTP server listening on some port that is accessible to your frontend. Then your frontend needs to make an AJAX request to your backend (most likely a POST request) and send the required data in the request body.
Now, your backend needs to handle the request, get the data and write it to the file or do whatever you want with that.
Things to keep in mind:
use body-parser if you're using Express
remember about CORS
It's easier if you use a higher level framework on the backend like Express, Hapi, Restify, LoopBack etc. instead of the low level http module in Node.
It's also easier if you use a framework on the frontend like jQuery, Angular, React, Aurelia, Ember etc.
The first step is to set up a RESTful POST operation (an HTTP POST) on your server. This is the typical service mechanism for what is sometimes called an AJAX call. Once you have the server set up to receive a string via the POST, you can serialize your objects on the client side and deserialize (reconstitute) the objects on the server side.
To serialize, you can use stringify on the client side. A simple web search for "stringify" will show you different ways to use stringify in a browser-independent, backward compatible way.
stringify(obj)
On the server side, node.js has a global JSON object. Use parse to reconstitute an object or objects from the string. Other major languages now have similar parser methods. 1
JSON.parse(strJSON)
To get started, you can test the mechanism with just one simple object. Then you can aggregate the objects in a JSON array or associative array and send them all at once in a single POST.
[1] There are frameworks that encapsulate this process, but it may be of value to you to NOT initially use them so you get a clear picture of the mechanics of a RESTful POST over the HTTP protocol. It is the key thing that a browser does when you submit an HTML form, and RESTful operations are key communications elements in today's IT world.

How can you access the HTTP response from a server using client-side JavaScript?

I'm trying to do client-side processing of some data sent in a server's HTTP response.
Here's what I'm working with: I have a web application that sends commands to a backend simulation engine, which then sends back a bunch of data/results in the response body. I want to be able to access this response using JavaScript (note..not making a new response, but simply accessing the data already sent from the server).
Right now, I am able to do this via a kludgy hack of sorts:
var responseText = "{{response}}";
This is using Django's template system, where I have already pre-formatted the template context variable "response" to contain a pre-formatted string representation of a csv file (i.e., proper unicode separators, etc).
This results in a huge string being transmitted to the page. Right now, this supports my immediate goal of making this data available for download as a csv, but it doesn't really support more sophisticated tasks. Also, I'm not sure if it will scale well when my string is, say, 2 MB as opposed to less than 1 KB.
I'd like to have this response data stored more elegantly, perhaps as part of the DOM or maybe in a cache (?) [not familiar with this].
The ideal way to do this is to not load the csv on document load, either as a javascript variable or as part of the DOM. Why would you want to load a 2MB data every time to the user when his intention may not be to download the csv everytime?
I suggest creating a controller/action for downloading the csv and get it on click of the download button.

jquery.post(): how do i honor a redirect from the server?

I'm trying my hand at unobtrusive JS, using JQuery in my Ruby On Rails app.
After the user fills out a form, the client-side JQuery code calls:
$.post("/premises", ui.form)
I can see the POST hit the server, and I can see the server emit a redirect notice to http://localhost:3000/users/42 complete with the data to be displayed.
But the browser page doesn't change. This doesn't really surprise me -- the whole point of client-side javascript is to control what gets updated -- I get that. But in this case, I'd like to honor whatever the server replies with.
I tried extending the call to post() based on How to manage a redirect request after a jQuery Ajax call:
$.post("/premises",
ui.item,
function(data, textStatus) {
if (data.redirect) {
// data.redirect contains the string URL to redirect to
window.location.href = data.redirect;
} else {
// data.form contains the HTML for the replacement form
$("#myform").replaceWith(data.form);
}
});
... but (among other problems) data.redirect is undefined. I suspect the real answer is simple, right? Looking forward to it!
The post you refer to uses JSON as return value and it is constructing that json on server side. it means if there is redirect your data object would look like
{redirect:'redirecturl.html'}
and if it is not redirect then data object would be like
{form:html-string-for-form}
now job is to construct json object accordingly on server side
The server is saying that the data you want to process with JavaScript is available at a different URL, not that the browser should load a new document into the top level frame. Sending the browser to the URL where it was told the data it was requesting with JS is wouldn't be honouring the redirect.
If you want to do that, then the server should respond with data (in the body of the response) that the JavaScript interprets as a reason to assign a new value to location.
data.redirect is probably undefined because you're not specifying it on the server side. In the answer you linked to the point was to have the server always respond with 200 regardless of the outcome, and then the JSON body it sends back determines how the client reacts. So, on the server side you'd want to respond with {"redirect" : "/where/to/go"}

Categories

Resources