I have to parse a response from the server,
The response is like..
[4,"1.0",1368544417760]
[1,"Great West Road","222",1368544595000]
[1,"Ruislip Manor Station","114",1368544479000]
[1,"Bank Station / Threadneedle Street","26",1368544731000]
[1,"Belvue School","E10",1368545955000]
[1,"Brunel Road","283",1368544706000]
[1,"Annesley Avenue","303",1368545930000]
[1,"Brixton Station Road","35",1368545854000]
[1,"Southampton Row","91",1368545537000]
[1,"Camden Road Station","29",1368545008000]
[1,"Fulham Cemetery","74",1368545210000]
The response doesn't seem to like JSON or XML.
Please help me know how to parse such type of response using Jquery.
I have to update the DOM based on the response and the response is getting updated
at a regular interval automatically.
The first number may be an indicator of what sort of data is in the rest of the "array".
I'd say
parse each line as if it were JSON. It'll turn into a javascript array.
var array = JSON.parse(oneLine); // Many browsers support this.
Then pull the bits out and put them into a proper object by name. (How to do that depends on the 1st element, perhaps.)
var obj = {};
if (array[0] == 1) {
obj.station = obj[1];
obj.number = obj[2];
obj.timestamp = obj[3]; // guessing what this is, too.
}
Do whatever you need with the data object.
Put all that in a loop. Repeat until done.
There is a similar Stack Overflow question here --> converting CSV/XLS to JSON?
Looks like there are a few different possible solutions that you could look at.
Related
I made a script to retrieve data from an API and show it in HTML.
The problem is that the API answers with something like that
[{"seen":"2021-08-24 04:13:51"}]
And I want the user to see something like
2021-08-24 04:13:51
How can i modify this text inside of javascript? (The output is variable but the number of characters is always the same, idk if this is a useful info...)
What you have to do is set innerText value from the JSON. You can access the value using response[0].seen
const response = [{"seen":"2021-08-24 04:13:51"}];
console.log(response[0].seen);
document.getElementById('lastupdatedon').innerText = response[0].seen;
<p id="lastupdatedon"></p>
The server is returning data in json format, you need to parse the response to a javascript object and then you can use the value as you want
const theServerResponse = '[{"seen":"2021-08-24 04:13:51"}]'
const parsedResponse = JSON.parse(theServerResponse)
//At this point you can get that value
parsedResponse[0].seen
Use below script
var fromAPI='[{"seen":"2021-08-24 04:13:51"}]';
var data=JSON.parse(fromAPI);
if(data!=null && data.length>0)
{
document.getElementById('lastupdatedon').innerText = data[0].seen;
}
HTML
<h3 id="lastupdatedon"></h3>
Do not forget to check for nulls, index is greater than 0. IF server doesnt return data then your app will throw an error of undefined.
I have a PHP script to which I make an Ajax request, and most of it works okay, but I'm having trouble accessing an array in the data returned to the JavaScript function.
So, the PHP has a bunch of regular variables, and one array. The array, $places, has four elements, which each have three values, as so:
[["z","815","1"],["w","2813","0"],["s","1582","2"],["b","1220","5"]]
A relevant excerpt of the PHP script is:
$encoded_places = json_encode($places); // if I don't do this then I end up with a value of "Array"
$qobject->name = "$name";
$qobject->multi = "$multi";
$qobject->places= "$encoded_places";
$myJSON = json_encode($qobject);
echo $myJSON;
In the JavaScript script (using JQuery), I successfully obtain the data from the Ajax request, and I can access all the data okay, except the $places data.
$.getJSON(url, function(data, status){
var stringified = JSON.stringify(data);
var parsedObj = JSON.parse(stringified);
var x = parsedObj.name; // alert(x); // which works fine
var myArray = new Array();
myArray.push(parsedObj.places);
for(var i = 0; i < myArray.length; i++){
console.log(myArray[i]);
}
... and the console will display what I'm expecting, namely:
[["z","815","1"],["w","2813","0"],["s","1582","2"],["b","1220","5"]]
However, I'm having difficulty accessing these values. For example, supposing I try to access the "815" portion of the first element, with something like: myArray[0][1], all I end up with is "[".
I guess somehow this whole piece of data is just a string, instead of an array, but I'm not familiar enough with JavaScript to quite know how to progress.
If, for example, I do this in the JavaScript script (hoping to see 815, 2813, 1582 and 1220 in the alerts) all I'll see is the single alert with "[". (i.e. it does the loop only once, and selects the character in position 1).
for(var i = 0; i < myArray.length; i++){
console.log(myArray[i]);
alert(myArray[i][1]);
}
I would very much appreciate someone explaining:
(a) how I can access the individual elements and values in JS
(b) how I can loop through them, although presumably once it's an array and not a string then the code above should do this.
Many thanks for any assistance.
Now Resolved:
As noted by #charlietfl, below, using quotes in
$qobject->places= "$encoded_places";
screwed things up, along with using json_encode on $places. However, without removing the quotes nothing worked either way. So, removed quotes and just used json_encode on the entire structure at the end, which now works fine.
So, the original snippet of code, given above, now looks like:
$qobject->name = $name;
$qobject->multi = $multi;
$qobject->places= $places;
$myJSON = json_encode($qobject);
echo $myJSON;
Change
$qobject->places = "$encoded_places";
To
$qobject->places = $places;
And get rid of the $encoded_places = json_encode($places); so that the one call to json_encode serializes the whole structure
Try this:
$.getJSON(url, function(data, status){
var parsedObj = JSON.parse(stringified);
console.table(parsedObj.places);
console.log(parsedObj.places)[0][0];
}
In the posted code's getJSON context, data is already a JSON string. So this line is redundantly stringifying your JSON string:
var stringified = JSON.stringify(data);
stringified is now set to a literal/escaped version of the valid JSON string from the data parameter:
[[\"z\",\"815\",\"1\"],[\"w\",\"2813\",\"0\"],[\"s\",\"1582\",\"2\"],[\"b\",\"1220\",\"5\"]]
When that double-stringified value is passed to JSON.parse for the parsedObj reference, it just becomes the original JSON string again (which looks deceptively correct in an alert box).
Strings are iterable in JavaScript, so the for loop was just going over the string.
I have tried searching and haven't been able to see anything that can parse in JavaScript.
It would only have to parse a .txt (tab delimited) file with the following:
L123____Donald____Duck____247.09
S234____Mickey____Mouse___356.09
F456____Daffy_____Duck____1650.36
N876____Minnie____Mouse___60.45
It would have to pull out the number, first initial of first name, first initial of second name and then the number at the end (concentration). The first 3 L123, D and D could all be given a var, but the concentration number would have to get a separate one as I have to do some funky calculations and the assign it function in a liquid handling robot.
Any help on this gratefully received, even if it's only partial as I like to try and work things out ( sometimes ;-) )
I use this to test things at the moment because I don't know what else to use: https://www.w3schools.com/js/
Thank you
var input = /* your data */;
var table = input.split("\n").map(line => line.split("\t")); // here's your table
I have 2 questions here :
Question 1.
How to concatenate multiple text and strings into one String variable and return the string?
function TagGen()
{
var getTitle="Nidome no Jinsei wo Isekai de Chapter 1 Raw Manga";
var getTag=getTitle.substring(0, getTitle.lastIndexOf(" Chapter"));
var setTags={""+getTitle+", "+getTitle+" Raw Manga"+", "+getTitle+", "+getTag+" Raw Manga"+", "+getTag+" Raw"+", "+getTag+" Manga Download"+", "+getTag+" Download"+", "+getTag+" jcafe"+", "+getTag+" Chapter Download,"+", "+getTag+" Raw Chapters"+", "+getTag+" jcafe24"+", "+"Raw Download"+", "+getTitle+" Raw Manga Download"+", "+getTitle+" jcafe"};
return setTags;
}
I want the setTags to be have the string value something like the below,
I tried to run this code several times in Tryit Editor but didn't get setTags variable working. Please help.
Question 2.
I want to store multiple tags of my blogger blog post into one String.
I know that there must be some b:loop used but I still have not yet fully understood its uses.
Suppose I have a post with the labels : Action,Adventure,Romance,Shounen
I want it to get all those labels and store it in a String like:
labels=Action,Adventure,Romance,Shounen
The basic idea of the saving into String is same as the first question but I don't know how to get multiple tags and do it.
Please help :D
To get all the labels present in a post into a variable in a concatenated form, you can use the following code -
<script>
var labelArray = <b:eval expr='data:post.labels map (label => label.name)' />;
var labels = labelArray.join(',');
</script>
This utilizes the Lambda operator map provided by Blogger.
The following code is working but extremely slow. Up till the search function all goes well. First, the search function returns a sequence and not an array (why?!). Second, the array consists of nodes and I need URI's for the delete. And third, the deleteDocument function takes a string and not an array of URI's.
What would be the better way to do this? I need to delete year+ old documents.
Here I use xdmp.log in stead of document.delete just te be safe.
var now = new Date();
var yearBack = now.setDate(now.getDate() - 365);
var date = new Date(yearBack);
var b = cts.jsonPropertyRangeQuery("Dtm", "<", date);
var c = cts.search(b, ['unfiltered']).toArray();
for (i=0; i<fn.count(c); i++) {
xdmp.log(fn.documentUri(c[i]), "info");
};
Doing the same with cts.uris:
var now = new Date();
var yearBack = now.setDate(now.getDate() - 365);
var date = new Date(yearBack);
var b = cts.jsonPropertyRangeQuery("Dtm", "<", date);
var c = cts.uris("", [], b);
while (true) {
var uri = c.next();
if (uri.done == true){
break;
}
xdmp.log(uri.value, "info");
}
HTH!
Using toArray will work but is most likely were your slowness is. The cts.search() function returns an iterator. So All you have to do is loop over it and do your deleting until there is no more items in it. Also You might want to limit your search to 1,000 items. A transaction with a large number of deletes will take a while and might time out.
Here is an example of looping over the iterator
var now = new Date();
var yearBack = now.setDate(now.getDate() - 365);
var date = new Date(yearBack);
var b = cts.jsonPropertyRangeQuery("Dtm", "<", date);
var c = cts.search(b, ['unfiltered']);
while (true) {
var doc = c.next();
if (doc.done == true){
break;
}
xdmp.log(fn.documentUri(doc), "info");
}
here is an example if you wanted to limit to the first 1,000.
fn.subsequence(cts.search(b, ['unfiltered']), 1, 1000);
Several things to consider.
1) If you are searching for the purpose of deleting or anything that doesnt require the document body, using a search that returns URIs instead of nodes can be much faster. If that isnt convenient then getting the URI as close to the search expression can achieve similar results. You want to avoid having the server have to fetch and expand the document just to get the URI to delete it.
2) While there is full coverage in the JavaScript API's for all MarkLogic features, the JavaScript API's are based on the same underlying functions that the XQuery API's use. Its useful to understand that, and take a look at the equivalent XQuery API docs to get the big picture. For example Arrays vs Iterators - If the JS search API's returned Arrays it could be a huge performance problem because the underlying code is based on 'lazy evaluation' of sequences. For example a search could return 1 million rows but if you only look at the first one the server can often avoid accessing the remaining 999,999,999 documents. Similarly, as you iterate only the in scope referenced data needs to be in available. If they had to be put into an array then all results would have to be pre-fetched and put put in memory upfront.
3) Always keep in mind that operations which return lists of things may only be bounded by how big your database is. That is why cts.search() and other functions have built in 'pagination'. You should code for that from the start.
By reading the users guides you can get a better understanding of not only how to do something, but how to do it efficiently - or even at all - once your database becomes larger than memory. In general its a good idea to always code for paginated results - it is a lot more efficient and your code will still work just as well after you add 100 docs or a million.
4) take a look at xdmp.nodeUrl https://docs.marklogic.com/xdmp.nodeUri,
This function, unlike fn.documentUri(), will work on any node even if its not document node. If you can put this right next to the search instead of next to the delete then the system can optimize much better. The examples in the JavaScript guide are a good start https://docs.marklogic.com/guide/getting-started/javascript#chapter
In your case I suggest something like this to experiment with both pagination and extracting the URIs without having to expand the documents ..
var uris = []
for (var result of fn.subsequence(cts.search( ... ), 1 , 100 )
uris.push(xdmp.nodeUri(result))
for( i in uris )
xdmp.log( uris[i] )