Extracting json properties from request body

148 views
Skip to first unread message

Julian May

unread,
Dec 22, 2015, 3:58:50 AM12/22/15
to ArangoDB
Hey

I can't/won't map requests directly to the model i need to store in the repository, so i need to extract properties from the json parameter.

I'm fighting a lot of ""TypeError: undefined is not a function"", when trying to find a method to extract the values fromt the json object, and with no prior javascript experionce, this is not telling me a lot.

I have this in my foxx-controller:


controller.post('/roomtypewasadded', function (req, res) {

var x = req.parameters.event;
res.json(x);

}).bodyParam('event', {description: 'The "RoomTypeWasAdded" event', type: DomainEvent});

Which returns the expected json:

{ "$type": "Xpectra.Events.PropertyManagement.RoomTypeWasAdded, Xpectra.Core", "RoomTypeId": "16f0f9b9-f518-414b-9c4b-0aa5b554abcf", "RoomTypeCode": "DB", "HexColorCode": "008000", "MaxPax": 3, "Description": "Double room" }
When requested like this:
curl -X POST --header "Content-Type: application/json" --header "Accept: application/json" -d "{
  \"RoomTypeId\": \"16f0f9b9-f518-414b-9c4b-0aa5b554abcf\",
  \"RoomTypeCode\": \"DB\",
  \"HexColorCode\": \"008000\",
  \"MaxPax\": 3,
  \"Description\": \"Double room\"


What I want to do is this:

controller.post('/roomtypewasadded', function (req, res) {

var x = req.parameters.event;

//Throws "TypeError: Connot read property 'type' of null" :,(
var rt = {
  roomTypeCode : x.RoomTypeCode,
  description : x.Description,
  maxPax : x.MaxPax
};

  roomTypeRepo.save(x);
  res.json(x.forClient());


}).bodyParam('event', {description: 'The "RoomTypeWasAdded" event', type: DomainEvent});


Which, when requested the same way, gives me this;


{
"exception": "TypeError: Cannot read property 'type' of null", "
"stacktrace": [ "TypeError: Cannot read property 'type' of null", " at [object Object].save (c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/share/arangodb/js/server/modules/org/arangodb/foxx/repository.js:188:24)", " at c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/var/lib/arangodb-apps/_db/_system/availability/APP/controllers/handler.js:40:16", " at Object.res.action.callback (c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/share/arangodb/js/server/modules/org/arangodb/foxx/internals.js:99:5)", " at c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/share/arangodb/js/server/modules/org/arangodb/foxx/routing.js:334:17", " at execute (c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/share/arangodb/js/server/modules/org/arangodb/actions.js:1309:7)", " at next (c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/share/arangodb/js/server/modules/org/arangodb/actions.js:1326:7)", " at BaseMiddleware.middleware (c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/share/arangodb/js/server/modules/org/arangodb/foxx/base_middleware.js:424:5)", " at execute (c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/share/arangodb/js/server/modules/org/arangodb/actions.js:1309:7)", " at routeRequest (c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/share/arangodb/js/server/modules/org/arangodb/actions.js:1330:3)", " at foxxRouting (c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/share/arangodb/js/server/modules/org/arangodb/actions.js:1081:7)", " at execute (c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/share/arangodb/js/server/modules/org/arangodb/actions.js:1309:7)", " at Object.routeRequest (c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/share/arangodb/js/server/modules/org/arangodb/actions.js:1330:3)", " at Function.actions.defineHttp.callback (c:\\Code\\XpectraDependencies\\ArangoDB-2.7.2-win64\\share\\arangodb\\js\\actions\\api-system.js:58:15)" ]
"TypeError: Cannot read property 'type' of null",
" at [object Object].save (c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/share/arangodb/js/server/modules/org/arangodb/foxx/repository.js:188:24)",
" at c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/var/lib/arangodb-apps/_db/_system/availability/APP/controllers/handler.js:40:16",
" at Object.res.action.callback (c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/share/arangodb/js/server/modules/org/arangodb/foxx/internals.js:99:5)",
" at c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/share/arangodb/js/server/modules/org/arangodb/foxx/routing.js:334:17",
" at execute (c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/share/arangodb/js/server/modules/org/arangodb/actions.js:1309:7)",
" at next (c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/share/arangodb/js/server/modules/org/arangodb/actions.js:1326:7)",
" at BaseMiddleware.middleware (c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/share/arangodb/js/server/modules/org/arangodb/foxx/base_middleware.js:424:5)",
" at execute (c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/share/arangodb/js/server/modules/org/arangodb/actions.js:1309:7)",
" at routeRequest (c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/share/arangodb/js/server/modules/org/arangodb/actions.js:1330:3)",
" at foxxRouting (c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/share/arangodb/js/server/modules/org/arangodb/actions.js:1081:7)",
" at execute (c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/share/arangodb/js/server/modules/org/arangodb/actions.js:1309:7)",
" at Object.routeRequest (c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/share/arangodb/js/server/modules/org/arangodb/actions.js:1330:3)",
" at Function.actions.defineHttp.callback (c:\\Code\\XpectraDependencies\\ArangoDB-2.7.2-win64\\share\\arangodb\\js\\actions\\api-system.js:58:15)"
], "
"error": true, "
"code": 400, "
"errorNum": 17, "
"errorMessage": "Cannot read property 'type' of null" }
}


My model schema looks like this:

var Foxx = require('org/arangodb/foxx'),
  Joi = require('joi'),
  RoomTypeInformation;

RoomTypeInformation = Foxx.Model.extend({
  schema: {
    _key: Joi.string(),
    roomTypeCode: Joi.string().required(),
    description: Joi.string(),
    maxPax: Joi.number().integer().required()
  }
});

module.exports = RoomTypeInformation;



Thanks in advance for any help or pointers 

he...@arangodb.com

unread,
Dec 22, 2015, 5:40:33 AM12/22/15
to ArangoDB
Hello,

I need a some more information to help you. Please give us all related code passages for your use case (repository: RoomTypeInformation, definition of DomainEvent, etc.)

roomTypeRepo.save(x);

Do you want to save 'x' here? Or variable 'rt'? 

Julian May

unread,
Dec 23, 2015, 4:24:45 AM12/23/15
to ArangoDB
Hey :)

Happy to oblige, though I would be happy to just return "rt" to client for now - the repository is not part of the problem at this point (as far as i can tell).
And yes, you are completely right, it is 'rt' i meant to save.
I've attached what little I have written yet of the Foxx. The "DomainEvent" model has no Joi instructions, the "RoomTypeInformation" model has a couple. 
The problem at hand is in the "handler" controller, at .post('/roomtypewasadded');

Thanks!

/Julian
availability.zip

he...@arangodb.com

unread,
Dec 23, 2015, 5:32:15 AM12/23/15
to ArangoDB
Hello,

there are two possible problems: 

1.) 

You define the object rt. This object has no function forClient() defined, but you call it. When you run 
res.json(rt.forClient());

it throws an error. So you just have to use rt, without the function. 
res.json(rt);

Or you have to define the function forClient()
rt.forClient = function() {
 
//your code goes here
};

2.) 

Could you please check if you have all required collections? Your app creates:
- availability_Checkpoint
availability_RoomAvailabilityOnDate
availability_RoomInformation
- availability_RoomTypeAvailabilitytModifier
availability_RoomTypeInformation

Maybe you deleted some of them during development? (Collections need to be prefixed with the app mountpoint)

he...@arangodb.com

unread,
Dec 23, 2015, 5:35:52 AM12/23/15
to ArangoDB
Also you can debug your code with: 

require("console").log("My log output goes here:", rt.forClient);

Then you would see that rt.forClient is undefined and will break the execution.

Julian May

unread,
Dec 23, 2015, 6:32:58 AM12/23/15
to ArangoDB
Thanks - being able to log what happens really helps :)

It is the "forClient" that needs implementing - I'm not clear on what i need to do though (seems forClient in regular input->repo scenarios "catches" the new id for the input in the collection??), could you give me a pointer?
Does the repository depend on the 'forClient' implementation? (and if so, how so?). Also, since the model i want to use for "rt" is already defined (RoomTypeInformation), can i do something like var rt = new RoomTypeInformation{ key : (value from 'x'} and avoid some redundant implementation?

I'm basing my conclusion (that the forClient is missing) on the fact that the "Roomtype forClient:"-line is never logged in this controller/output:


controller.post('/roomtypewasadded', function (req, res) {

var x = req.parameters.event;

logger.log("Testing 1-2");

//Throws "TypeError: undefined is not a function"
var rt = {
  roomTypeCode : x.RoomTypeCode,
  description : x.Description,
  maxPax : x.MaxPax
};

logger.log("Testing 3-4");

logger.log("Roomtype obj:", rt);

logger.log("Roomtype forClient:", rt.forClient());

  roomTypeRepo.save(rt);
  res.json(rt.forClient());


}).bodyParam('event', {description: 'The "RoomTypeWasAdded" event', type: DomainEvent});

Log output:
2015-12-23T11:22:45Z [10228] INFO Testing 1-2
2015-12-23T11:22:45Z [10228] INFO Testing 3-4
2015-12-23T11:22:45Z [10228] INFO Roomtype obj: { "roomTypeCode" : "DB", "description" : "Double room", "maxPax" : 3 }
2015-12-23T11:22:45Z [10228] ERROR Error in foxx route '{ "match" : "/handler/roomtypewasadded", "methods" : [ "post" ] }': 'undefined is not a function', Stacktrace:
2015-12-23T11:22:45Z [10228] ERROR TypeError: undefined is not a function
2015-12-23T11:22:45Z [10228] ERROR   at c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/var/lib/arangodb-apps/_db/_system/av/APP/controllers/handler.js:48:38
2015-12-23T11:22:45Z [10228] ERROR   at Object.res.action.callback (c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/share/arangodb/js/server/modules/org/arangodb/foxx/internals.js:99:5)
2015-12-23T11:22:45Z [10228] ERROR   at c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/share/arangodb/js/server/modules/org/arangodb/foxx/routing.js:334:17
2015-12-23T11:22:45Z [10228] ERROR   at execute (c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/share/arangodb/js/server/modules/org/arangodb/actions.js:1309:7)
2015-12-23T11:22:45Z [10228] ERROR   at next (c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/share/arangodb/js/server/modules/org/arangodb/actions.js:1326:7)
2015-12-23T11:22:45Z [10228] ERROR   at BaseMiddleware.middleware (c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/share/arangodb/js/server/modules/org/arangodb/foxx/base_middleware.js:424:5)
2015-12-23T11:22:45Z [10228] ERROR   at execute (c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/share/arangodb/js/server/modules/org/arangodb/actions.js:1309:7)
2015-12-23T11:22:45Z [10228] ERROR   at routeRequest (c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/share/arangodb/js/server/modules/org/arangodb/actions.js:1330:3)
2015-12-23T11:22:45Z [10228] ERROR   at foxxRouting (c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/share/arangodb/js/server/modules/org/arangodb/actions.js:1081:7)
2015-12-23T11:22:45Z [10228] ERROR   at execute (c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/share/arangodb/js/server/modules/org/arangodb/actions.js:1309:7)
2015-12-23T11:22:45Z [10228] ERROR   at Object.routeRequest (c:/Code/XpectraDependencies/ArangoDB-2.7.2-win64/share/arangodb/js/server/modules/org/arangodb/actions.js:1330:3)
2015-12-23T11:22:45Z [10228] ERROR   at Function.actions.defineHttp.callback (c:\Code\XpectraDependencies\ArangoDB-2.7.2-win64\share\arangodb\js\actions\api-system.js:58:15)

he...@arangodb.com

unread,
Dec 23, 2015, 7:49:25 AM12/23/15
to ArangoDB
Your rt object is only a normal JavaScript object. It has no toClient function implemented. If you want to use the toClient function you could just create a foxx model like you described above (new RoomTypeInformation ... ). With that model you can call the toClient method. But you can also just return your rt object. Using the model may be more pretty.

Julian May

unread,
Dec 28, 2015, 3:39:42 AM12/28/15
to ArangoDB
Ok. Got it sorted. My initial problem of extracting the property-values from the json object was solved with the following:

var x = JSON.parse(req.requestBody);

Probably something too obvious to state in documentation, since basic javascript experience is expected when working with Foxx, but thought I'd leave here for others who might have the same issue.
Thanks for your input he..., and happy holidays/new year!

/Julian

he...@arangodb.com

unread,
Dec 28, 2015, 5:33:15 AM12/28/15
to ArangoDB
If you use the req.requestBody, you have to parse the string to valid JSON, thats true.
But if you use req.parameters, you do not have to parse it because you get a JSON object back. 

Julian May

unread,
Dec 28, 2015, 8:04:16 AM12/28/15
to ArangoDB
... Then is it possible that using dot-notation to a req.parameter named "event" conflicts with something javascript'ish?
I always got a blank/empty object from req.parameters.event, hence my confusion.
Reply all
Reply to author
Forward
0 new messages