I'm currently using node-ews in a project to access an Exchange Web Server via node.js. Now i ran into a weird problem. To run for example a "CreateItem" request, which can be an E-Mail or Appointment for example, I'm giving the function the arguments as a json similar to this
var args = {
"attributes" : {
"SendMeetingInvitations" : "SendToAllAndSaveCopy"
},
"SavedItemFolderId": {
"DistinguishedFolderId": {
"attributes": {
"Id": "calendar"
}
}
},
"Items" : {
"CalendarItem" : {
"Subject" : "",
"Body" : {
"attributes" : {
},
"$value" : ""
},
"ReminderIsSet" : "true",
"ReminderMinutesBeforeStart" : "30",
"Start" : "",
"End" : "",
"IsAllDayEvent" : "false",
"LegacyFreeBusyStatus" : "Busy",
"Location" : ""
}
}
};
As the REST-API I'm writing will receive Attributes like Subject, Start, End etc. I initially stripped out those out of the JSON and would define them later like
args.Items.CalendarItem.Subject = req.body.Subject;
Oddly this will make the internal validation of node-ews fail and tell me that CalendarItem has an invalid Child Subject. If i leave Subject als an empty string in the initial args and later change it set it to req.body.Subject it works just fine.
My question is this: Is the Object somewhat different if I later add attributes and if yes is there a way to do it right? Because I don't think its the best way to have a bunch of empty Attributes in my Object if they aren't used and define standard values for all of them even if api won't require them to be sent.
Would great if someone knew the answer. Hope i could clarify what the problem is
Ok,
so the problem seems to be this. Internally the JSON "object" seems to have an order based on the order the variable is defined. in JavaScript this is no problem. But when the xml is parsed, the tag that was defined last will also be at the end of the xml so if you had
<someTag>
<variable2 />
<variable3 />
</someTag>
and you add variable1 to your json by someTag.variable1 = x in the end the xml will look like this after beeing parsed by node-ews
<someTag>
<variable2 />
<variable3 />
<variable1 >x</variable1>
</someTag>
Now unfortunately the exchange web server seems to be picky about the order of the xml tags. so when you build your json be sure to use the direct order. Changing content of the json later will not affect the order.
Related
rookie here. I've searched and searched and still remain ignorant.
I am making an array of markers/info windows for a Google Maps API. Currently, I have succeeded in loading my markers from an external JSON file. JSON data looks like this: https://codedump.io/share/5XUwRzOFvREi/1/json-array
pathway ./json/Markers
{"Markers": [
{
"title" : "Meow Monestary",
"position" : {
"lat" : 40.5178,
"lng" : -122.6438
},
"posterContact" : {
"name" : "Mr Meowser",
"email" : "MrMeow#Couch.com",
"phone" : "(555)-202-3040",
"private" : true
},
"type" : "myResidence",
"ownerContact" : {
"name" : false,
"email" : false,
"phone" : false,
"private" : true
},
"description" : "Meow meow purrrrr. Dogs are not my favorite but they are my second favorite.",
"private" : true
},
I want users to be able to fill out a form containing all of this data and then push the new marker object into the JSON array. So far I have collected the form, created a Javascript object, and converted it to a JSON string like this...
function submitForm(){
//place form data into array
var formData = $("#shelterForm").serializeArray();
//build the javascript object using the values in the array
var shelter = {
title:formData[0].value,
position:{
lat:formData[1].value,
lng:formData[2].value
},
posterContact:{
name:formData[3].value,
email:formData[4].value,
phone:formData[5].value,
private:formData[6].value
},
type:formData[7].value,
ownerContact:{
name:formData[8].value,
email:formData[9].value,
phone:formData[10].value,
private:formData[11].value
},
description:formData[12].value,
private:formData[13].value
};
shelterString = JSON.stringify(shelter);
}
I'm sure there was an easier way to do this. If you feel inclined to go into this... GREAT!! My main issue though is that now I have my JSON string, but can't figure out how to push it into my array. I'm thinking maybe pass the string to PHP and write to file, or possibly ajax allows this?
Whether or not you use AJAX, you will still need a script on the server to save the data server side. Doing an AJAX request is more advanced than just a regular form POST, so I would recommend against it for a beginner.
Once the data is sent to PHP, you will need to store it. The most common way this would be done is with a database, typically MySQL. When the form is posted, you would get the data from the $_POST variable and store it as a new row in the database. Then, for the JSON file, rather than using a static file, you would point the maps to a PHP script for the external JSON file. That script would then query the database, assemble the data into an associative array with code very much like your javascript submitForm() function, and then call json_encode() to convert that array into a JSON string that it would then print. On the client side, you would not need your submitForm() function anymore.
If you don't want to mess around with a database, you can use a regular file on your server and have the PHP script modify that file. It is a little messier, though, and if you have an error in your script or the server loses power while writing the file, you could lose all your data, so I would recommend also setting up a daily backup if you have important data in the file. Also, you will have to take special precaution to not allow two different people to submit their updates at the same time, since having two processes writing to the same file concurrently will cause garbage data. Databases are built to be more resilient to these problems out of the box.
If you want to go the file route, you would probably still want to move the creation of the JSON into PHP. Your javascript relies on the exact indicies of the form elements, and is hard to read and maintain. In PHP, you would have something like:
$shelter = [
'title' => $_POST['shelter_title'],
'position' => [
'lat' => $_POST['shelter_latitude'],
'lng' => $_POST['shelter_latitude']
],
The $_POST keys are the name attributes from your form elements, which makes it much easier to maintain than using index numbers, which would have to be renumbered if you added or removed a form field.
Then, you would need to lock the json file to make sure that two processes don't try to update it at the same time
if (!flock($json_filename,LOCK_EX)) {
die('We are having trouble updating our records. Please try again later.');
}
//Now nobody else can write to the file until the script finishes or calls flock($json_filename, LOCK_UN) to release the lock
Then, we load the old JSON file, and update it with our new record:
$old_json = file_get_contents($json_filename); //get JSON data as string
$old_data = json_decode($old_json); //convert JSON data into PHP array
$new_data = array_push($old_data['Markers'], $shelter); //add the new shelter to PHP array
$new_json = json_encode($new_data); //convert the PHP array back to a JSON string
file_put_contents($json_filename, $new_json); //write the string to the file
//json file is updated, so now you can display a message, or redirect the user to a new page with header('Location: foo')
I haven't tested this code, so back up your JSON before trying this.
What you should be doing here, is to have a local json file to which the google map api would be pointed to and to add to that file using the html form with a php action where you would ingest the form data and add it to the json file.
<form action="addJson.php" method="post">
addJson.php (to get the general idea)
<?php
$localFile = 'json/Markers.json';
$data = [$_POST]; // reformat if required
$existing = json_decode(file_get_contents($localFile));
$all = array_merge($existing,$data);
file_put_contents($localFile,json_encode($all));
echo 'thanks for addition';
?>
And you can totally omit the javascript submitForm function.
My database is formatted like this:
{
"latitude" : 41.884629,
"longitude" : -87.648764,
"name" : "Bar Siena",
"placeID" : "ChIJf3h_t9osDogReehZO7Hgk50",
"vibes" : {
"LGpswrvLgfYppcBG4bpmNzXQVoU2" : {
"rating" : 1,
"timestamp" : 1.477961061358844E9
},
"OSzA2KhTBWS3pxVnCZ6eScAuNDG3" : {
"rating" : 5,
"timestamp" : 1.477955566836665E9
}
}
}
I want to pull both the names of each bar, and every rating corresponding to it in the vibes table. My code looks like this:
firebase = pyrebase.initialize_app(config)
db = firebase.database()
for i in range(1,100):
venues = db.child("venues").child(i).get()
dict = (venues.val())
print(dict['name'])
So far i'm only able to get the names, but i'm not sure how to go deeper and get the ratings. My database is managed using Firebase, and I'm using a python library called Pyrebase that's just a wrapper for the javascript api. I'm having trouble because each vibe has a generated hash key so i'm not sure how to go deeper. Any thoughts?
vibes probably comes as a dictionary. What you want are the ratings of each hash key, so you can do something like
for hashkey, vibe_dict in dict['vibes'].items(): # dict is a Python keyword, so it's a bad choice for a variable!
print(hashkey, vibe_dict['rating'])
I am not sure about firebase, but in plain python you may do it like:
>>> for vibe in my_json['vibes'].values():
... print vibe['rating']
...
1 # Rating of item 1
5 # Rating of item 2
where my_json is the dict build from your json:
{
"latitude":41.884629,
"longitude":-87.648764,
"name":"Bar Siena",
"placeID":"ChIJf3h_t9osDogReehZO7Hgk50",
"vibes":{
"LGpswrvLgfYppcBG4bpmNzXQVoU2":{
"rating":1,
"timestamp":1.477961061358844E9
},
"OSzA2KhTBWS3pxVnCZ6eScAuNDG3":{
"rating":5,
"timestamp":1.477955566836665E9
}
}
}
If your venues variable is a JSON-like object as in example, you can use the standart json library to work with it:
import json
dict_data = json.loads(venues)
print dict_data['latitude']
Btw, it's a bad style of development - to overwrite built-in Python funuctions. In your example you're overwriting dict(dict is a default Python type-object)
I have a simple user info document which includes a completion field.
Mapping:
"properties" : {
"fname" : { "type" : "string" },
"lname" : { "type" : "string" },
"dob" : { "type" : "string" },
"sex" : { "type" : "string" },
"autocomplete" : {
"type" : "completion"
}
}
This is an example of my document.
"person" : {
"sex" : "Male",
"dob" : "11/11/2014",
"fname" : "Julie",
"lname" : "Thomas",
"autocomplete" : "Julie Thomas"
}
The complete suggestion query works perfectly fine. But when I delete this document, the complete suggestion still exist for "Julie Thomas" when I expect this to be deleted as well.
Any suggestion on what I am doing incorrectly?
Thanks!
I am having this problem too. According to the ElasticSearch documentation, completion suggestions need to be expunged from the index using the Optimize command. This is what they say at the bottom of the Completion Suggester Docs.
The suggest data structure might not reflect deletes on documents
immediately. You may need to do an Optimize for that. You can call
optimize with the only_expunge_deletes=true to only cater for deletes
or alternatively call a Merge operation.
... that said. I did this:
curl -XPOST 'http://server:9200/attribute/_optimize?pretty' -d '{
"only_expunge_deletes": true
}'
and the deleted doc still shows up in the completion suggester, even though it does not show up in queries or filters.
... Sorry. Not much of an answer... It's supposed to be the answer, but it might not work for you, just as it's not working for me.
We might have to move to Index-Time Search, which uses a 1-character ngram and do a normal _search query.
Adding an id field to the data, and then refrencing that id field for delete and update, works for us
"index":{"_index":"esIndex","_type":"document","_id":"23d68f060118fbeee699d14eff044a1f"}}
{"text":"vision zero","id":"23d68f060118fbeee699d14eff044a1f","suggest":{"input":"vision zero","payload":{"entity_id":"23d68f060118fbeee699d14eff044a1f"}},"type":"Content"}
Something like the above bulk query data, notice the id field in the data. If we don't put it, we face same issue that after deleting document, it still show up in suggestions.
So here is the issue. I have a straight export from mongodb collection as json flat file. I am trying to get my phantomjs app to read and parse the flat file from MongoDB and convert it into an object for phantomjs to parse. For some reason I cannot parse the JSON string normally.
(note: NO jQuery solutions. This needs to be raw javascript)
Here is my flat file from mongodb. It seems fine:
{ "host" : "www.myfoxphilly.com", "path" : "/category/233430/entertainment", "created_at" : { "$date" : 1375199393295 }, "_id" : { "$oid" : "51f7e0a1dc12a13510000002" } }{ "host" : "www.news9.com", "path" : "/category/112032/news", "created_at" : { "$date" : 1375285798173 }, "_id" : { "$oid" : "51f9322668ee1e660c000001" } }{ "host" : "www.myfoxphilly.com", "path" : "/category/233430/entertainment", "created_at" : { "$date" : 1375285823602 }, "_id" : { "$oid" : "51f9323f68ee1e660c000002" } }
Here is the config file that is attempting to parse the above JSON flat file
var fs = require('fs');
var data = fs.read('configData.json');
var newdata = JSON.stringify(data);
var dataobj = eval("["+newdata+"]");
console.log(typeof(newdata));
exports.tests = dataobj;
// Sample object (works fine like this):[{path:'/category/112043/sports' ,host:'www.newson6.com'}];
exports.getFileName = function(test,local) {
return 'results/' + test.host.replace(/\./g,'-').replace(/\:[0-9]+/,'').replace('-com','').replace('www-','') + test.path.replace(/\//g,'-').replace(/\?clienttype=/g, "clienttype") + ((local) ? '-locl' : '-prod')
}
So when I run phantom, I get no data. That JSON becomes one single object, instead of the object example I have in the comment section.
If I just replace the JS common library flat file import and make "data" a string, it works just fine, like so:
var data = '{"host" : "www.myfoxphilly.com", "path" : "/some/path/233409"}';
Is there some sort of issue going on with the js common library file import when I import the JSON in as a string? Help please.
ONCE AGAIN, no jQuery, I will down vote you without looking. I <3 jQuery, but you guys need to realize when it's appropriate to use (i.e. browser-based js).
OMG! You used eval ... :P I'm suprised this question hasn't already been down voted 5 times.
On the real, excellent question.
Your problem, if #DCoder has actually posted an answer, is your JSON. A 'flat file from mongodb' is not necessarily valid JSON. Further, to make it valid you're gonna need to parse the string first:
wrap it in square braces
make sure you have a comma after each data line exported from mongo.
Seriously, eval? Use JSON.parse twice on your converted string.
That should solve it. Everything else looks clean.
(.. eval .. I cant believe this scrub)
I have some strange porblem with jQuery. From a web socket I get the following JSON string:
{
"time" : 1373772581860,
"entries" : {
"OK" : 2,
"FASTER" : 1,
"SLOWER" : 2
},
"entriesSize" : 3,
"setEntries" : true,
"setTime" : true
}
After receiving it I would like to retrieve the values of entries so that I know how many votes OK has, how many FASTER and how many SLOWER. If I try this by saying msg.data.entries.FASTER jQuery fails with TypeError: msg.data.entries is undefined. Why is that. I tried it in JS Fiddle and it just worked fine. See here. Does anybody know why jQuery is acting that strange and different in different environments? Thanks.
First parse returned json string to object.
var jsonObject = $.parseJSON(msg);
Then access required data from decoded object.
e.g. var time = jsonObject.time;