json/ajax confusion - ajax

I've got a response that sends back an entire table. N number of rows with 7 cells in each row. So I end up with nX7 responses. Apparently, I should be using JSON to handle the string appropriately. I've found tutorials on how to create a JSON object, but not so much on how to send it via ajax and how in sending it through ajax, the jsp knows to fill the JSON object with the responses... In other words,
I create JSON object in javascript (check)
place JSON object in the ajax code (confused)
response with JSON object filled (confused)
Parse JSON object so I can get at the data easily (maybe confused, we'll see after steps 2/3)
I am not using jquery as I'm still learning and jquery's syntax is confusing currently.
var sweekStart = document.getElementById("weekStart").value;
var smonth = document.getElementById("month").value;
var syear = document.getElementById("year").value;
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
var url = "empTableRepop.jsp?weekStart=" + encodeURIComponent(sweekStart)+"&month="+encodeURIComponent(smonth)+"&year="+encodeURIComponent(syear);
xmlhttp.open("POST",url,true);
//alert("made it to open");
xmlhttp.onreadystatechange = function(){
if(xmlhttp.readyState == 4){
//alert(xmlhttp.responseText);
var test = xmlhttp.responseText;
reFillTable(test);
}
}
xmlhttp.send(null);
The variable "test" (yea, bad name but it's temporary) is the object I want converted from a standard var to a JSONobject. If I understand correctly, JSON will already have the string parsed when it receives the response. I realise I can change "function()" to be directly "reFillTable(test)" but given the path it took me to get it working I ended up with that somehow lol. Will fix once everything is working properly.
EDIT:
This is how I "display" the information from the jsp/java file.
//Name Cell
out.println(empName);
//Mondays Hours
out.println(hoursArr[0]);
//Tuesdays Hours
out.println(hoursArr[1]);
//Wednesdays Hours
out.println(hoursArr[2]);
//Thursdays Hours
out.println(hoursArr[3]);
//Fridays Hours
out.println(hoursArr[4]);
//Total hours Cell
out.println(PTOAmt);

Assuming that your serverresponse is already working, this gives you the JavaScript object from the received JSON.
var test = JSON.parse( xmlhttp.responseText );
To clarify: There is no explicit "JSONObject" in JavaScript. JSON stands for JavaScript Object Notation and is simply a shorthand for writing normal JavaScript objects. It became, however, popular as a means of serializing data to send through AJAX-request.
In the end the server just sends a string in JSON format, which you on the other hand have to parse again (by JSON.parse()) in order to have an object representing the data send.
Just to add: JSON.stringify() is the operation in the other direction. Creating a string out of a JavaScript object.
With respect to the edit:
As said in the comment, this does not create valid JSON (have a look # json.org for an overview).
So now you have some choices:
Use a library like GSON to encode your data.
Parse your data by hand in JavaScript. (I would not recommend this).
Create a valid JSON string manually.
The code for the third option, may look like this:
// start the JSON object
out.print( "{" );
//Name Cell
out.println( "\"empName\":\"" + empName + "\"," );
// start an array for the next few values
out.print( "\"hours\": [" );
out.print(hoursArr[0] + "," );
out.print(hoursArr[1] + "," );
out.print(hoursArr[2] + "," );
out.print(hoursArr[3] + "," );
out.print(hoursArr[4] + "," );
// end the array
out.print( "]," );
//Total hours Cell
out.print( "\"PTOAmt\":\"" + PTOAmt + "\"");
// end the JSON
out.print( "}" );
This assumes that PTOAmt is a string as well.
On the long run you should use a library like mentioned in option (1) to handle the encoding.

Related

Google Photos API - How to filter albums to get photos (JPEG) only while having albumId set?

I'm trying to filter contents of an album (to get photos only) coming form Google Photos API, but the docs say that:
Filters shouldn't be used in a mediaItems:search request if the
albumId is set. If a filter is used when the albumId is set, an
INVALID_ARGUMENT error (400) is returned.
Does this mean that I have to download all files, than filter the response my self using the MIME type? Or can it still be done directly in the request?
Thanks!
My code:
var params = JSON.parse(localStorage.getItem('oauth2-params'));
var xhr = new XMLHttpRequest();
xhr.open('POST',
'https://photoslibrary.googleapis.com/v1/mediaItems:search?' +
'access_token=' + params['access_token'] +
'&pageSize=25' +
'&albumId=' + albumId +
'&pageToken=' + this.albums[albumId].photos.nextPagination);
xhr.responseType = "json";
xhr.onreadystatechange = (e) => {
if (xhr.readyState === 4 && xhr.status === 200) {
// handling the respons...
} else if(xhr.readyState === 4) {
console.log(xhr.status, xhr.response);
}
};
xhr.send(null);
Unfortunately, you can't specify both a media type and album as a parameter for a search request at the moment. There's a request for this on the issue tracker here. You can 'star' the issue to be notified of any updates.
For now, you can do the filtering on your side, without needing to download the files themselves: Check the mimeType and the mediaMetadata properties of a media item. The mimeType field indicates what kind of file it is (for example, image/jpeg or image/png). Alternatively, you can also check whether the mediaMetadata property contains a photo.

outlook add-in image & files

I try to find solution to my problems but didn't find any where,hope that someone here can save me.
I write add-in in JavaScript on VS2015 that encrypte and decrypte body messages.
1. The first problem is with images that the receiver can't see .
(Talk about images that copy into the body by "insert picture inline" button)
In Compose mode we encrypte the message and then when we decrypte it's works good because the compose mode is a client side and he his recognize the local images .
In read mode when user want to decrypte the message and to see the images he couldn't see because the encrypte prevent outlook to convert the local image to data on the server .
In my code I take the body message like this ( compose mode )
item.body.getAsync(
item.body.getAsync(
"html",
{ asyncContext: "This is passed to the callback" },
function callback(resultbody) {
......Here we send the body for ENCRYPT.
}))
then , the user send the encrypte message by clicking 'send' regular.
In the read mode I just print it to my html to check if the decrypte is good :
(JSON.parse(xhr.responseText).Data.Content));
and then i get icon of picture ,but not success to show the real pic .
The src of the icon is going for place that not access for him ..
<img src="https://attachment.outlook.office.net/owa/*****/service.svc/s/GetFileAttachment?id=AAMkADUwMDE0YWM1LTYwODctNG ......
How can i take this tag of image and do something that the receiver can see the image ? I don't want that user will be need to upload image to body from my my add-in instead of the original outlook. I try to convert the image to base-64 string, but with what I have in the tag it not enough ,just with original picture and also it success to show in html but not in the body of message with SetAsync function..
2. The second problem is with attachments .
I upload files with dropzone plug-in (because outlook don't give access to take attachment and change him). So, after I upload files and encrypte him I make some new file with the response from server with File API of JS :
ar f = new File([""], "filename.txt", {type: "text/plain", lastModified: date}) . .. .
than I want to attach the file to mail, so the only method that do this is:
addFileAttachmentAsync(uri, attachmentName, optionsopt, callback opt)
then,I need to create a url for file for this method so I use this method:
var objectURL = URL.createObjectURL(f);
But now when I use the method addFileAttachmentAsync with objectURL it's write that there is a problem and its can't attach it , I think that the URL is incorrect .
Thanks all!!
For everyone who look any solution to this problems..
**In outlook web this solutions works good but in Outlook Desktop there is a problem of synchronize with server so there is a delay with saveAsync function without any solution to this right now , so it's work but need to wait a little bit.You could read more about it here.
First Question:
There is a problem in outlook add-in with when using getAsync and then setAsync functions . The problem occurs when there is some image inside the body . It's happen because when you take the body in Html format and then return the body with some different the image still not 'upload' and the src is being wrong .
I success to workaround this problem using Outlook rest API.
So the workaround is going like this:
Get the body message in type of Html by getAsync method. create div
element and set the return body message inside the div.
To get message id, you need to save your message as a draft with saveAsync function.
To make request to Outlook rest
API you need to get access token , so call to getCallbackTokenAsync function and save the access
token.
Make Http Request to outlook rest API to get all attachment exist in
the message.
Find the right ID of your image and replace the image src to the
base-64 of the image that you get from your request to outlook rest
API.
Finally , you could set your new body with SetAsync function .
Code:
item.body.getAsync(
Office.CoercionType.Html,
{ asyncContext: "This is passed to the callback" },
function callback(resultbody) {
var bodyDiv = document.createElement('div');
bodyDiv.innerHTML = content;
Office.context.mailbox.item.saveAsync(
function callback(result) {
var myNewItemSaved = result.value;
Office.context.mailbox.getCallbackTokenAsync({ isRest: true },
function (result) {
if (result.status === "succeeded") {
var accessToken = result.value;
var itemId = "";
if (Office.context.mailbox.diagnostics.hostName === 'OutlookIOS')
itemId = Office.context.mailbox.item.itemId;
else
itemId = Office.context.mailbox.convertToRestId(myNewItemSaved,
Office.MailboxEnums.RestVersion.v2_0);
var xhr3 = new XMLHttpRequest();
xhr3.open("GET", "https://outlook.office.com/api/v2.0/me/messages/" + itemId + "/attachments", true);
xhr3.setRequestHeader("Content-type", "application/json");
xhr3.setRequestHeader("Access-Control-Allow-Origin", "*");
xhr3.setRequestHeader("Authorization", "Bearer " + accessToken);
xhr3.send();
xhr3.onreadystatechange = function () {
if (xhr3.readyState == 4) {
if (xhr3.status == 200) {
var allImages = JSON.parse(xhr3.response).value;
var isDesktop = false;
var imgSrcId = bodyDiv.getElementsByTagName('img')[0].getAttribute("src");
if (imgSrcId.indexOf("cid") != -1) //Outlook Desktop
isDesktop = true;
for (var i = 0; i < allImages.length; i++) {
if (bodyDiv.getElementsByTagName('img')[i].getAttribute("src").indexOf("base64")!=-1)
continue;
if (isDesktop)
imgSrcId = bodyDiv.getElementsByTagName('img')[i].getAttribute("src");
else
imgSrcId = bodyDiv.getElementsByTagName('img'[i].getAttribute("originalsrc");
imgSrcId = imgSrcId.substr(4, imgSrcId.length);
var wantedImg;
for (var j = 0; j < allImages.length; j++) {
if ((allImages[j].ContentId).localeCompare(imgSrcId) != -1) {
wantedImg = allImages[j]; break;}
}
bodyDiv.getElementsByTagName('img')[i].src = 'data:' + wantedImg.ContentType + ';base64,' + wantedImg.ContentBytes;
}
}
setAsync......
}
}}}})})};
Second question
The problem with addFileAttachmentAsync that this is work only with files that is on external server, and it's not add a blob , local files.
So also here the solution is with Outlook rest API . The solution will attach our file to the message but we can't see this-no preview of the attachment in message , but when we send it this will attach to message , and we could see in our message that the attachment is there.
The solution is really similar to the one of the image in body - Save the message as a draft , get access token and this time the Http Request will be 'POST' request to our message id to attach our file to the current message.
Code to the request to add attachment to message ( all the way until here is the same like question 1):
var attachment ={
"#odata.type": "#Microsoft.OutlookServices.FileAttachment",
"Name": "smile.png",
"ContentBytes": "AAACFAMxLjAeKUDndY7EKF4P7QiWE7HgHLa7UiropGUTiDp5V07M0c5jaaTteauhzs0hOU+EOmVT0Lb6eSQ2MzgkCre/zCV9+kIB9PjWnOzoufau67J9PQdXapsOQSMcpt9X2QpcIjnl7H3sLu9iu2rqcvSjwhDnK6JygtghUB405EZHZ9LQcfJ1ZTYHylke2T9zbViq2BPqU/8IHZWsb/KQ/qzV4Jwv3NHnI583JvOuAtETJngh964edC4cU2IY6FkIWprksRw7d4fEQ/+3KbEyW0trIZm59jpTSV01/PhOI0RDKj1xI1Vr+lgMRZpOrYDfChWWWbByNzSXbIsTjHMU6GmQ5Cb09H3kv/2koFa5Pj2z8i+NGywYKw8ZSu3NVblM9I0EkQVLrxkM8gqyrDEtAobxPRxEzGTEXdnjws5UIiiGFBq3khuxejFGCNvUbmPM9guVZO0ccDe1FICTFHkrPlLZW/TvJYMou0HBrvH7s4taBHyZw5x03dhps+WG19D5na44vaVX2Vni6ZrrxfqFo7JTUpCJxCcPyoG7/nEWtJ/V/J+oXdypeapN9Agl6Q81WvCbzuyZgbLTfj6NXWDoliie069Hvk/k2lP+HyO7Iu5ffeRX2WWguwdfGXiNbqInrxn18tX+N7/KqWbRJv96tmijdCmCvsF9Lpr9k7QFKB93wuHfTuE6Qi2IVNBfzNBaz1iJYjY="
}
var xhr4 = new XMLHttpRequest();
xhr4.open("POST", "https://outlook.office.com/api/v2.0/me/messages/" + itemId + "/attachments", true);
xhr4.setRequestHeader("Content-type", "application/json");
xhr4.setRequestHeader("Access-Control-Allow-Origin", "*");
xhr4.setRequestHeader("Authorization", "Bearer " + accessToken);
xhr4.send(JSON.stringify(attachment));
xhr4.onreadystatechange = function () {
if (xhr4.readyState == 4) {
if (xhr4.status == 200)
console.log("ok");
else
console.log(xhr4.response);
}};
Hope it's will help someone , good luck !

How to load image list from REST API using angularJS

I have searched in this forum for quiet a bit and here's my problem -
I have a ng-repeat in my html which takes in a list of messages(Json object).
Each message JSON has a sender email address - e.g. abc#gmail.com
Now, I have to get the email address from the message and form another REST API request to fetch their images for e.g. - http://<>:8080/getImage/abc#gmail.com (email address dynamic)
So in my code, I'll have a ng-repeat and a ng-src pointing to the image REST URL
If there's no image in server, it returns a 404 and displays a broken image on the UI. How do I handle it? On the other hand, if I make a http request to determine if there's a success message and on failure return a default image, then the whole thing goes through an endless loop. I'll try to create a fiddle and include it for better explanation.
Use the error block to handle such behavior:
function($http) {
var restUrl = 'getImage/abc';
return {
fetchImage: function(imageId) {
var self = this;
return $http.get(restUrl + '/' + imageId).
success(function(data) {
return self.imageUrl = data;
}).
error(function(data) {
return self.imageUrl = "pathToDefaultImage";
});
},
...

JSON output from web method

I have a web method returning JSON to a fullCalendar as event data but a "()" is added to it causing a parser error.
I am able to clip off the unwanted "()" and then attach the events with jQuery but obviously don't want to keep it this way.
The source of the data is a web method using Razor. Using the JSON helper to encode the data results in a well formed JSON string, i.e. no "()". Of course if I use encode I then would use Response.Write to send the data back to the AJAX function. The same ill formed JSON data is recieved if I use JSON.Write(data, Response.Output).
Catching the returned data in the success function shows the data with the attached "()".
Here is a portion of the web method that returns the data:
// convert the header names and data to strings
var rows = from e in cE
select new
{
id = e.EvId,
title = e.Title,
start = e.startT,
allDay = false,
end = e.endT,
backgroundColor = e.eventColor
};
string mJson = Json.Encode(rows);
//Json.Write(rows, Response.Output);
Response.Write(mJson.Trim());
here is the result of the encode:
"[{\"id\":9,\"title\":\"new event\",\"start\":\"2012-05-29 19:00:00\",\"allDay\":false,\"end\":\"2012-05-29 20:00:00\",\"backgroundColor\":\"Orange \"},{\"id\":9,\"title\":\"new event\",\"start\":\"2012-06-05 19:00:00\",\"allDay\":false,\"end\":\"2012-06-05 20:00:00\",\"backgroundColor\":\"Orange \"},{\"id\":9,\"title\":\"new event\",\"start\":\"2012-06-12 19:00:00\",\"allDay\":false,\"end\":\"2012-06-12 20:00:00\",\"backgroundColor\":\"Orange \"},{\"id\":10,\"title\":\"another\",\"start\":\"2012-06-22 19:00:00\",\"allDay\":false,\"end\":\"2012-06-22 19:45:00\",\"backgroundColor\":\"Orange \"},{\"id\":10,\"title\":\"another\",\"start\":\"2012-06-29 19:00:00\",\"allDay\":false,\"end\":\"2012-06-29 19:45:00\",\"backgroundColor\":\"Orange \"}]" string
Here is what the AJAX success function shows as the recieved data:
"[{"id":9,"title":"new event","start":"2012-05-29 19:00:00","allDay":false,"end":"2012-05-29 20:00:00","backgroundColor":"Orange "},{"id":9,"title":"new event","start":"2012-06-05 19:00:00","allDay":false,"end":"2012-06-05 20:00:00","backgroundColor":"Orange "},{"id":9,"title":"new event","start":"2012-06-12 19:00:00","allDay":false,"end":"2012-06-12 20:00:00","backgroundColor":"Orange "},{"id":10,"title":"another","start":"2012-06-22 19:00:00","allDay":false,"end":"2012-06-22 19:45:00","backgroundColor":"Orange "},{"id":10,"title":"another","start":"2012-06-29 19:00:00","allDay":false,"end":"2012-06-29 19:45:00","backgroundColor":"Orange "}]();???"

parsing a reponse from a XMLHttpRequest

I'm struggling with how to parse a response from an XMLHttpRequest. The response is in json format:
http://flickr.com/services/rest/?method=flickr.photos.search&api_key=75564008a468bf8a284dc94bbd176dd8&tags=paris&format=json
to make sure it does indeed come in as such i tested it:
document.getElementById('info').innerHTML = this.responseText
which returns me a page with a long line of data written in json format. Could someone help me figure out the next steps in order to extract data from the response i.e. a list of all titles
i did some research and came across this:
response = this.responseText ;
var doc = new DOMParser().parseFromString(response, "text/xml");
what do i need to do next?
(Note: i wish to do this manually i.e. without the help of jQuery or similar tools.)
[EDIT]
based on the suggestions below and on the Flickr page on that matter, i have tried the following:
request.onreadystatechange = function()
{
...
if (this.responseXML != null)
{
jsonFlickrApi(this.responseText) ;
function jsonFlickrApi(rsp){
for (var i=0; i<rsp.photos.photo.length; i++){
var blog = rsp.photos.photo[i];
var div = document.createElement('div');
var txt = document.createTextNode(photo.owner);
div.appendChild(txt);
//document.body.appendChild(div);
document.getElementById('info').innerHTML.appendChild(div);
}
...
}
this doesn't return anything visible yet.
[EDIT2]
further troubleshooting reveals:
rsp = this.responseText ;
document.getElementById('info').innerHTML = rsp.stat ;
prints undefined
The URL you've given returns somethins like this :
jsonFlickrApi({"photos":{"page":1, "p ... , "stat":"ok"})
So, basically, it looks like Javascript code, which :
Calls the jsonFlickrApi function,
Passing it a big JSON object as a parameter.
First of all, here, you are working with JSON, so you should not use any DOM-related stuff : DOM functions' goal is to help manipulate XML.
Instead, you should :
Write a jsonFlickrApi function,
Make sure it's called when you receive the data from Flickr
About that, you shuld find a bit more informations, and an example, here : http://www.flickr.com/services/api/response.json.html
Else, adding the &nojsoncallback=1 parameter at the end of the URL of your request, you'll get pure-JSON as a result (and not a function-call).
That would allow you to use standard JSON-manipulation functions to work with that data, not having to implement any specific function.
Between those solutions, up to you to choose which one you prefer :-)
A different alternative is not to use JSON at all, and use XML instead. Leave out the format=json part of the URL and you get the data as XML. This XML can be parsed, for example with the DOMParser() method you tried, or with this.responseXML. However, the "logistics" of using XML, compared to JSON, are a bit more complicated, as you're browsing a DOM tree and not a JS object.
Update:
So here's one of the murky details of AJAX. Depending on the browser, you can't just make XML requests between domains. The following code will work (return something useful) on Safari, but not Firefox or Chrome. (There, it will return null or empty strings.) The JSON requests seem to work fine without on all browsers, however.
<script>
function createXHR(){
if (window.XMLHttpRequest){
// code for IE7+, Firefox, Chrome, Opera, Safari
return new XMLHttpRequest();
}
if (window.ActiveXObject){
// code for IE6, IE5
return new ActiveXObject("Microsoft.XMLHTTP");
}
return null;
}
function getFlickr(){
xmlhttp=createXHR();
url="http://www.flickr.com/services/rest/?method=flickr.photos.search&api_key=75564008a468bf8a284dc94bbd176dd8&tags=paris&";
xmlhttp.onreadystatechange=stateChanged;
xmlhttp.open("GET",url,true);
xmlhttp.send(null);
}
function stateChanged(){
if (xmlhttp.readyState==4){
alert(xmlhttp.getAllResponseHeaders());
alert(xmlhttp.responseXML)
alert(xmlhttp.responseText)
var xmlDoc=xmlhttp.responseXML.documentElement;
}
}
getFlickr();
</script>
The cool thing about JSON is that it's actually executable code. You don't need to do any "manual" parsing – just run the code. Perhaps Flickr supplies a function called jsonFlickrApi with their API libs that they exepct you to use, but you could just as well supply your own.
function parseFlickrJson(jsonstring){
var data=null;
var jsonFlickrApi=function(d){
data = d;
}
eval(jsonstring);
return data;
}
myreturndata = parseFlickrJson(response);
// Try getting something from the object
alert(myreturndata.photos.pages);

Resources