0

I have the array of objects called res and am trying to loop through and organize the objects based on having one href, one method, and in some cases multiple schema, as with: href: '/questions/{id}'

My issue is when I have multiple schema, if the current object I am in has '$schema' I want to check if the next object in the array also has '$schema'. If it does then I want to label the current schema object, requestSchema and the next object will be called responseSchema. But if the next object does not contain '$schema' then the current object will be labeled responseSchema.

I want to take res and turn it into

[{
 "resource": "/questions",
 "verb": "GET",
 "schemaResponse": {
 "$schema": "http://json-schema.org/draft-04/schema#",
 "type": "object",
 "properties": {
 "data": {
 "type": "array",
 "items": [{
 "type": "object",
 "properties": {
 "question": {
 "type": "string",
 "enum": [
 "Favourite programming language?"
 ]
 },
 "published_at": {
 "type": "string",
 "enum": [
 "2014-11-11T08:40:51.620Z"
 ]
 },
 "url": {
 "type": "string",
 "enum": [
 "/questions/1"
 ]
 },
 "choices": {
 "type": "array",
 "items": [{
 "type": "object",
 "properties": {
 "choice": {
 "type": "string",
 "enum": [
 "Javascript"
 ]
 },
 "url": {
 "type": "string",
 "enum": [
 "/questions/1/choices/1"
 ]
 },
 "votes": {
 "type": "number",
 "enum": [
 2048
 ]
 }
 },
 "required": [
 "choice",
 "url",
 "votes"
 ],
 "additionalProperties": false
 }]
 }
 },
 "required": [
 "question",
 "published_at",
 "url",
 "choices"
 ],
 "additionalProperties": false
 }]
 }
 },
 "required": [
 "data"
 ]
 }
 }, {
 "resource": "/questions/{id}",
 "verb": "GET",
 "schemaRequest": {
 "$schema": "http://json-schema.org/draft-04/schema#",
 "type": "object",
 "properties": {
 "id": {
 "type": "number"
 }
 },
 "required": [
 "id"
 ]
 },
 "schemaResponse": {
 "$schema": "http://json-schema.org/draft-04/schema#",
 "type": "object",
 "properties": {
 "question": {
 "type": "string",
 "enum": [
 "Favourite programming language?"
 ]
 },
 "published_at": {
 "type": "string",
 "enum": [
 "2014-11-11T08:40:51.620Z"
 ]
 },
 "url": {
 "type": "string",
 "enum": [
 "/questions/1"
 ]
 },
 "choices": {
 "type": "array",
 "items": [{
 "type": "object",
 "properties": {
 "choice": {
 "type": "string",
 "enum": [
 "Javascript"
 ]
 },
 "url": {
 "type": "string",
 "enum": [
 "/questions/1/choices/1"
 ]
 },
 "votes": {
 "type": "number",
 "enum": [
 2048
 ]
 }
 },
 "required": [
 "choice",
 "url",
 "votes"
 ],
 "additionalProperties": false
 }]
 }
 },
 "required": [
 "question",
 "published_at",
 "url",
 "choices"
 ],
 "additionalProperties": false
 }
 }
]

Everything works except for in the case of needing to have a request schema and a response schema.

const lodash = require('lodash');
var res = [ 
 { href: '/questions' },
 { method: 'GET' },
 { '$schema': 'http://json-schema.org/draft-04/schema#',
 type: 'object',
 properties: { data: [Object] },
 required: [ 'data' ] },
 { href: '/questions/{id}',
 hrefVariables: { element: 'hrefVariables', content: [Object] } },
 { method: 'GET',
 headers: { element: 'httpHeaders', content: [Object] } },
 { '$schema': 'http://json-schema.org/draft-04/schema#',
 type: 'object',
 properties: { id: [Object] },
 required: [ 'id' ] },
 { '$schema': 'http://json-schema.org/draft-04/schema#',
 type: 'object',
 properties: 
 { question: [Object],
 published_at: [Object],
 url: [Object],
 choices: [Object] },
 required: [ 'question', 'published_at', 'url', 'choices' ] } ]
 var arr = [];
 var arrFinal = [];
 var result = {};
 for (var key = 0; key < res.length; key++) {
 console.log(res[key]);
 console.log(key);
 var found = false;
 for(var i = 0; i < arr.length; i++) {
 //console.log((lodash.has(res[key], 'href')));
 //console.log((lodash.has(res[key-1], '$schema'))); 
 if ((lodash.has(arr[i], 'href'))) {
 found = true;
 break;
 }
 }
 if ((lodash.has(res[key], '$schema')) && (lodash.has(res[key-1], '$schema'))) {
 console.log('here');
 result.schemaResponse = res[key];
 result = lodash.omit(result, ['headers', 'properties', 'hrefVariables', 'required', 'href', 'method']);
 break;
 }
 if((found === true) && (lodash.has(res[key], '$schema'))) {
 var result = {}; 
 console.log('there') 
 var combinedKeys = arr.reduce(function(a, item) {
 Object.keys(item).map(function(key) {
 if(key === 'href'){
 result.resource = item[key];
 }
 if(key === 'method'){
 result.verb = item[key];
 } else {
 result[key] = item[key];
 } 
 });
 return result;
 }, {});
 arr = [];
 if((lodash.has(res[key+1], '$schema'))){
 result.schemaRequest = res[key];
 } else {
 result.schemaResponse = res[key];
 result = lodash.omit(result, ['headers', 'properties', 'hrefVariables', 'required', 'href', 'method']);
 arrFinal.push(result);
 result = {};
 }
 }
 else {
 console.log('hmmm');
 var object = res[key];
 arr.push(object); 
 }
 }
 var string = JSON.stringify(arrFinal, null, ' ')
 console.log(arrFinal)
asked Jul 11, 2016 at 3:45
13
  • Your question was a little unclear (I'd suggest proofreading it again and breaking up some of the run-on sentences). Are you saying that when you evaluate if ((lodash.has(res[key], '$schema')) && (lodash.has(res[key-1], '$schema'))) the value res[key-1] is always undefined?. So basically the 2nd if block never executes? Commented Jul 11, 2016 at 14:04
  • @jusopi Yes that is exactly what I am saying. I am trying to go to either the next or previous object in the array and check if it has '$schema'. But am not sure why what I have does not seem to do the trick. Commented Jul 11, 2016 at 14:15
  • When key = 0 k-1 = -1 which is out of bounds. Similarly, when key = length -1 (the last element in the array) key + 1 = length which is out of bounds. Adding if checks for these two situations should fix this issue. Commented Jul 11, 2016 at 14:40
  • @nurdyguy would not checking those cases cause the value to always be undefined though? Also where should I implement those checks? Commented Jul 11, 2016 at 14:42
  • can you please explain "what" you want to do and leave the "how's" out because they're obviously not working? Let others come up with the working how. Commented Jul 11, 2016 at 14:42

1 Answer 1

1

Based on this:

My issue is when I have multiple schema, if the current object I am in has '$schema' I want to check if the next object in the array also has '$schema'. If it does then I want to label the current schema object, requestSchema and the next object will be called responseSchema. But if the next object does not contain '$schema' then the current object will be labeled responseSchema.

and this (from my comment on your question):

Your question was a little unclear (I'd suggest proofreading it again and breaking up some of the run-on sentences). Are you saying that when you evaluate if ((lodash.has(res[key], '$schema')) && (lodash.has(res[key-1], '$schema'))) the value res[key-1] is always undefined?. So basically the 2nd if block never executes

Here is some pseudo-code to work into your code:

 for ( var nIdx, crnt, next, key = 0, m = res.length; key < m; key++ ){
 crnt = res[ key ]
 next = res[ key + 1 ]
 //do your checking here based on the existence of 'next'
 if (next){ .... }
}

I'd test this on a simple loop and log the values of crnt and next to see if you're actually getting the expected results. If they are as expected, you can adjust your code to use those values instead of trying to access them dynamically with res[ key ] further down in your code.

I dunno, what the issue really is with your code, but this will be more readable at the least and will probably illuminate your error.

answered Jul 11, 2016 at 15:46

2 Comments

Is k supposed to be key?
yep, typo. it's fixed

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.