JSON Output Formatting?

The forum to discuss the Headless version of Servoy. Web, Java and Servlet development questions can all be posted here.

JSON Output Formatting?

Postby bcusick » Wed Feb 22, 2017 12:34 am

Hey Guys,

I'm working with the RESTful plugin - and I was wondering how to properly (consistently) format the JSON output?

For example I have some object in code:

Code: Select all
var oProblem = {
   "id" : "",
   "problem" :  "",
   "date_added" : "",
   "date_resolved" : ""
}


Then I fill it up:

Code: Select all
oProblem.id = xxxx;
oProblem.problem = "Problem";
.... etc ...


The issue is - when the JSON comes out - it's in a different order:

Code: Select all
{
  "date_resolved" : "",
   "id" : xxxx,
   "problem" :  "Problem",
   "date_added" : ""
}


Is there a way I can keep it in the order I've specified (so it will match my API schema)?

Thanks in advance!

Bob
Bob Cusick
bcusick
 
Posts: 1170
Joined: Wed Apr 23, 2003 11:27 pm
Location: Thousand Oaks, CA USA

Re: JSON Output Formatting?

Postby david » Wed Feb 22, 2017 3:59 am

You access objects by key and arrays by index. Hence order of keys in object is not necessary (and not guaranteed in javascript). Said another way, the value of "oProblem.id" is always returned no matter the order "id" shows up as. Conversely, "oProblem[0]" is never used to get the value of the first key in an object.

Example of iterating objects in Servoy:

Code: Select all
/**
* @properties={typeid:35,uuid:"BD1E4BB4-F1B1-48C5-81BB-1571CD142A5B",variableType:-4}
*/
var myObjectSimple = function() {
   return {
      a: 1,
      b: 2,
      c: "3"
   }
}

/**
* @properties={typeid:35,uuid:"F1E8AC6B-6884-44C3-9C58-6A4B1ED7CB54",variableType:-4}
*/
var myObjectClosure = function () {
   // total up all numbers with startValue
   var aggregate = function (inputArray, startValue) {
      
      // inputArray is Array?
      if (Array.isArray(inputArray)) {
         inputArray.filter(function(item) {
            return typeof item === "number"
         })
         .map(function (item) {
            startValue += item
         })
      }
      return startValue
   }
   return {
      a: 1,
      b: 2,
      c: "3",
      calc: aggregate
   }
}

/**
* USAGE:    #1 processObject(myObjectSimple)  // output order not guaranteed
*             -> a: 1.0
*             -> b: 2.0
*             -> c: 3 
*          #2 processObject(myObjectClosure) // w/method on the object
*             -> a: 1.0
*             -> b: 2.0
*             -> c: 3
*             -> calc: 3.0 // result of object "api" method
*
* @properties={typeid:35,uuid:"C142B794-16A4-4D8E-9DC5-A64F6C690B3A",variableType:-4}
*/
var processObject = function (factoryFN) {
   var newObject = factoryFN()
   
   // Iterate object version #1
//   if (typeof newObject[prop] === "function") {
//      var sum = newObject[prop]([newObject.a, newObject.b, newObject.c], 0) // example of calling newObject.calc(...) at the destination
//      application.output(prop + ": " + sum)
//   }
//   else {
//      application.output(prop + ": " + newObject[prop])
//   }

   // Iterate object version #2 (preferred)
   Object.keys(newObject).forEach(function (prop) {
   if (typeof newObject[prop] === "function") {
      var sum = newObject[prop]([newObject.a, newObject.b, newObject.c], 0) // example of calling newObject.calc(...) at the destination
      application.output(prop + ": " + sum)
   }
   else {
      application.output(prop + ": " + newObject[prop])
   }
})


Iterating objects in the browser (after calling your REST api endpoint for example) is similar (replace "application.output(...)" with "console.log(...)")
David Workman, Kabootit

Image
Everything you need to build great apps with Servoy
User avatar
david
 
Posts: 1723
Joined: Thu Apr 24, 2003 4:18 pm
Location: Washington, D.C.

Re: JSON Output Formatting?

Postby ROCLASI » Wed Feb 22, 2017 7:26 am

Hi Bob,

bcusick wrote:Is there a way I can keep it in the order I've specified (so it will match my API schema)?


Is there a specific reason to keep it in order?
As David already mentioned the order has no effect on accessing the data since you need to access it directly by property name.
If it's for display/document purposes you could keep an array with the property names in the correct order and iterate over that to fetch the values in order.
And as David already showed (although kinda buried in the code) you can get an Array with the property names of an object using the Object.keys(myObject) function.

Hope this helps.
Robert Ivens
ROCLASI Software Solutions / JBS Group, Partner
SAN Developer / Servoy Valued Professional / Servoy Certified Developer
Twitter: @roclasi / @servoyforge
--
ServoyForge - Building Open Source Software.
PostgreSQL - The world's most advanced open source database.
User avatar
ROCLASI
Servoy Expert
 
Posts: 5184
Joined: Thu Oct 02, 2003 9:49 am
Location: Netherlands/Belgium

Re: JSON Output Formatting?

Postby bcusick » Wed Feb 22, 2017 3:46 pm

Thanks guys! I know that the order doesn't matter - I was just wondering if there was a way to "prettify" the output. I know that there is no guaranteed "order" when working with object properties... but I just wanted to make sure I wasn't missing something really obvious. :D

David - I appreciate your in-depth explanation!

Robert - that's the route that I was going to go down if all else failed.

Again, many thanks to both of you!

Bob
Bob Cusick
bcusick
 
Posts: 1170
Joined: Wed Apr 23, 2003 11:27 pm
Location: Thousand Oaks, CA USA

Re: JSON Output Formatting?

Postby david » Wed Feb 22, 2017 5:42 pm

bcusick wrote:Thanks guys! I know that the order doesn't matter - I was just wondering if there was a way to "prettify" the output. I know that there is no guaranteed "order" when working with object properties... but I just wanted to make sure I wasn't missing something really obvious. :D


Yea, nothing at the end of that hole. But on a closely related note, changing up your object structure slightly to include an array of keys is a useful pattern. You can still directly access a specific object value by key (one step further removed, ie myObj.items.key instead of myObj.key) and you iterate the additional array of keys to process the keys in order:

Code: Select all
/**
* @properties={typeid:35,uuid:"33E547AA-6395-4EF9-8562-F1A6E6BB5301",variableType:-4}
*/
var myObjectOrdered = function() {
   return {items: {
            a: 1,
            b: 2,
            c: "3" },
         itemsOrder: ['a', 'b', 'c']
   }
}

/**
*
* USAGE:    processObjectOrdered(myObjectOrdered)  // output order guaranteed
*             -> [ 1.0, 2.0, 3 ]
*
* @properties={typeid:35,uuid:"9C49ECBB-A2AA-461A-AB39-33FD0530DBE5",variableType:-4}
*/
var processObjectOrdered = function(factoryFN) {
   var newObject = factoryFN()
   var sampleOutput = []
   
   // Iterate array and use to access object keys
   if ( newObject.hasOwnProperty('itemsOrder') && Array.isArray(newObject['itemsOrder']) ) {
      newObject['itemsOrder'].forEach(function(value) {
         sampleOutput.push(newObject['items'][value])
      })
   }
   
   application.output(sampleOutput)
}


For example if you're passing back functions instead of scalar values you could execute those functions in order and just choose a specific function to execute.
David Workman, Kabootit

Image
Everything you need to build great apps with Servoy
User avatar
david
 
Posts: 1723
Joined: Thu Apr 24, 2003 4:18 pm
Location: Washington, D.C.

Re: JSON Output Formatting?

Postby bcusick » Fri Feb 24, 2017 7:10 pm

David - VERY interesting!

Thanks very much for the tip!
Bob Cusick
bcusick
 
Posts: 1170
Joined: Wed Apr 23, 2003 11:27 pm
Location: Thousand Oaks, CA USA

Re: JSON Output Formatting?

Postby goldcougar » Thu Mar 02, 2017 7:06 am

a bit late on this, but with JSON, order isn't important (general) as others have mentioned. If you need to return things in a certain order, then you'll need to use an array in the JSON. Then the order is kept.

Normal Unordered JSON:
Code: Select all
var oProblem = {
   "id" : "",
   "problem" :  "",
   "date_added" : "",
   "date_resolved" : ""
}


Array Ordered JSON:
Code: Select all
var oProblem = [
   {"id" : ""},
   {"problem" :  ""},
   {"date_added" : ""},
   {"date_resolved" : ""}
]


So the ordered one is an array of objects/fields. Downside is it adds an extra level of nesting.
Scott Butler
iTech Professionals, Inc.
SAN Partner

Servoy Consulting & Development
Servoy University- Free Training Videos
Servoy Guy- Free Plugins, Tips & Resources
ServoyForge- Open Source Servoy Components
User avatar
goldcougar
Servoy Expert
 
Posts: 655
Joined: Sun Jan 08, 2006 7:15 am
Location: Cincinnati, OH

Re: JSON Output Formatting?

Postby bcusick » Fri Mar 03, 2017 4:31 pm

Scott - WHOA! That's really awesome! THANK YOU for that tip!

I was really just trying to see if I was missing something - but as long as I write docs that are clear - and document all the properties, datatypes, etc - it should be usable.

As this is my first stab at an API - I just didn't want to "Bob-ify" it and screw the pooch. :lol:
Bob Cusick
bcusick
 
Posts: 1170
Joined: Wed Apr 23, 2003 11:27 pm
Location: Thousand Oaks, CA USA


Return to Servoy Headless Client

Who is online

Users browsing this forum: Majestic-12 [Bot] and 1 guest