How to get json object in botpress custom component?

I am calling an api from botpress which returns a list of objects which I need to display in my custom component, but I always get it as string "[object Object]" if I use console.log(JSON.parse(this.contentArray)) I get below exception

Uncaught SyntaxError: Unexpected token o in JSON at position 1
at JSON.parse (<anonymous>)
at eval (eval at render (VM449 lite.bundle.js:10992), <anonymous>:1:18)
at InfaLinkPreview.render (VM449 lite.bundle.js:10992)
at finishClassComponent (react-dom.development.js:14741)
at updateClassComponent (react-dom.development.js:14696)
at beginWork (react-dom.development.js:15644)
at performUnitOfWork (react-dom.development.js:19312)
at workLoop (react-dom.development.js:19352)
at renderRoot (react-dom.development.js:19435)
at performWorkOnRoot (react-dom.development.js:20342)
at performWork (react-dom.development.js:20254)
at performSyncWork (react-dom.development.js:20228)
at requestWork (react-dom.development.js:20097)
at scheduleWork (react-dom.development.js:19911)
at Object.enqueueSetState (react-dom.development.js:11169)
at Web.push../node_modules/react/cjs/react.development.js.Component.setState (react.development.js:335)

It seems I am missing something in the custom component.

Server call api node and Infa link preview node screenshot showing session.response

botpress emulator screenshot showing value of session.response

modules\custom-component\src\content-types\infa-link-preview.js

const base = require('./_base');

function render(data) {
  const events = [];
  return [{
	type: 'custom',
	module: 'custom-component',
	component: 'InfaLinkPreview',
	text: data.text
  }]
}

function renderElement(data, channel) {
  if (channel === 'web' || channel === 'api') {
	return render(data);
  }
  return []; // TODO
}

module.exports = {
  id: 'custom_linkpreview',
  group: 'Custom Component',
  title: 'Infa Link Preview',
  jsonSchema: {
	description: 'Displays content of an array of KB/Docs/Video links',
	type: 'object',
	required: ['text'],
	properties: {
	  text: {
		type: 'string',
		title: 'Message'
	  },
	  variations: {
		type: 'array',
		title: 'Alternates (optional)',
		items: {
		  type: 'string',
		  default: ''
		}
	  },
	  ...base.typingIndicators
	}
  },
  uiSchema: {
	text: {
	  'ui:field': 'i18n_field',
	  $subtype: 'textarea'
	},
	variations: {
	  'ui:options': {
		orderable: false
	  }
	}
  },
  computePreviewText: formData => 'Infa Link Preview: ' + formData.text,
  renderElement: renderElement
}

modules\custom-component\src\views\lite\components\InfaLinkPreview.jsx

export class InfaLinkPreview extends React.Component {
  noAnswer = "Sorry no answer found."
  contentArray = this.props.text

  getTimestamp = () => {
	let date = new Date();
	let options = {
	  month: "short",
	  day: "numeric", hour: "2-digit", minute: "2-digit"
	};
	return date.toLocaleTimeString("en-us", options);
  }
  render() {
	console.log("InfaLinkPreview.jsx: " + JSON.stringify(this.contentArray));
	if (this.contentArray[0].query_status == "answer_available") {
	  return (
		<div className="linkPreviewMain">
		  <p className="linkPreviewTitle"><b>{this.contentArray[0].answer[1].title}</b></p>
		  <p className="linkPreviewDesc">{this.contentArray[0].answer[1].content}</p>
		  <small className="linkPreviewTimestamp">{this.getTimestamp()}</small>
		</div>
	  )
	} else {
	  return (
		<div className="infaTextMain">
		  <p className="infaTextMessage">{this.noAnswer}</p>
		  <small className="infaTextTimestamp">{this.getTimestamp()}</small>
		</div>
	  )
	}
  }
}

Note: Using Botpress v11.9.5

Update with response json from network

In this JSON session.response is correct but responses.text comes as [object Object] . So somehow while providing session.response to InfaLinkPreview component, this is going wrong.

Please help me figure out what is going wrong in infa-link-preview.js or InfaLinkPreview.jsx file.

{
	"responses": [{
			"type": "custom",
			"module": "custom-component",
			"component": "InfaLinkPreview",
			"text": "[object Object]"
		}
	],
	"nlu": {
		"entities": [],
		"language": "en",
		"slots": {},
		"intent": {
			"name": "none",
			"confidence": 1,
			"context": "global"
		},
		"intents": [{
				"name": "none",
				"confidence": 1,
				"context": "global"
			}
		],
		"errored": false,
		"includedContexts": ["global"],
		"ms": 738
	},
	"suggestions": [],
	"state": {
		"user": {},
		"context": {},
		"session": {
			"lastMessages": [{
					"eventId": "156183685440297440",
					"incomingPreview": "hii",
					"replyConfidence": 1,
					"replySource": "dialogManager",
					"replyDate": "2019-06-29T19:34:17.244Z",
					"replyPreview": "#!custom_infatext--mgyiK"
				}, {
					"eventId": "156183685440297440",
					"incomingPreview": "hii",
					"replyConfidence": 1,
					"replySource": "dialogManager",
					"replyDate": "2019-06-29T19:34:17.260Z",
					"replyPreview": "#!builtin_single-choice-FxG4EN"
				}, {
					"eventId": "156183686163322750",
					"incomingPreview": "No",
					"replyConfidence": 1,
					"replySource": "dialogManager",
					"replyDate": "2019-06-29T19:34:24.103Z",
					"replyPreview": "#!custom_infatext-ZSUgWA"
				}, {
					"eventId": "156183686163322750",
					"incomingPreview": "No",
					"replyConfidence": 1,
					"replySource": "dialogManager",
					"replyDate": "2019-06-29T19:34:24.106Z",
					"replyPreview": "#!custom_infatext-bO33uu"
				}, {
					"eventId": "156183688271887300",
					"incomingPreview": "How to install secure agent on linux?",
					"replyConfidence": 1,
					"replySource": "dialogManager",
					"replyDate": "2019-06-29T19:34:47.378Z",
					"replyPreview": "#!custom_linkpreview-Zple6W"
				}
			],
			"extractedSlots": {},
			"response": [{
					"answer": {
						"1": {
							"content": "this article provides details on how the nnn secure\nagent can be installed on linux the steps are as follows 1 log on to your\nnnn org and download the linux secure agent installer  agent64_install bin 2   log on to linux server as non root user and create a directory the secure agent will be\ninstalled in this directory for example in our environment we logged on\nto linux machine as a non root user admin\nand created a directory mylinuxagent 3 copy the  downloaded agent installer file to the linux server\nand run agent64_install bin as shown in the following screenshots                   4 once the installation is complete navigate to mylinuxagent apps agentcore directory and start the secure agent using the command infaagent\nstartup       5 now run the command consoleagentmanager sh\n  getstatus  to get information on the status of the secure agent   6 the above screenshot indicates that  the secure agent needs to be registered with your\nnnn org run consoleagentmanager sh  configure  and enter  your nnn org username and password   admin aaaa agentcore consoleagentmanager sh configure test nnn com test123\njava_home data admin mylinuxagent apps agentcore jre\nlogin succeeds admin aaaa agentcore consoleagentmanager sh isconfigured\njava_home data admin mylinuxagent apps agentcore jre\ntrue 7 using the commands shown in step 6 above the secure agent should get registered with your nnn org   check the status of the secure agent a couple of times\nusing consoleagentmanager sh getstatus     after some time the status should get changed to ready which indicates that\nthe secure agent has been installed successfully and is fully up and running     8 login to your nnn org configure runtime environments and click on the linux secure agent the process server\nand the data integration server should be up and running       one thing to note is that in the above screenshot the\nprocess server component of the secure agent will be available only if your nnn org is licensed for\nnnn cloud realtime icrt",
							"source": "KB",
							"title": "Install nnn Secure Agent on Linux",
							"url": "https://kb.nnn.com/howto/6/Pages/20/513826.aspx"
						},
						"2": {
							"content": "silent install to specified target location can be done by using the following command agent64_install bin i silent duser_install_dir target directory  ",
							"source": "KB",
							"title": "Install a Linux secure agent in a specified location using Silent install",
							"url": "https://ncom/howto/6/Pages/19/5094.aspx"
						},
						"3": {
							"actual_title": "Install and register the Secure Agent on Linux",
							"content": "",
							"name": {
								"NERAction": ["install", "register"],
								"NERComponent": ["secure_agent"],
								"NEROS": ["linux"]
							},
							"source": "DOC",
							"title": "Install and register the Secure Agent on Linux",
							"url": "https://n/install-and-register-the-secure-agent-on-linux.html"
						}
					},
					"query_status": "answer_available"
				}
			]
		},
		"temp": {}
	},
	"decision": {
		"decision": {
			"reason": "no suggestion matched",
			"status": "elected"
		},
		"confidence": 1,
		"payloads": [],
		"source": "decisionEngine",
		"sourceDetails": "execute default flow"
	}
}

@sylvain can you please help with this?

Use something like:

const data = JSON.parse(this.contentArray);
if (data.hasOwnProperty("id")){
    console.log(data .id);
}

I have already tried this and gives above exception because in chrome network tab I get it as string "[object Object]". Please check my network response

Hello @abhisheksimon, you will not be able to achieve this using the Call API method. It’s only for basic needs. If you have a complex object to manage, your custom component should call directly your api using Axios.

The complete event isn’t available on the webchat, only the “displayable” payload is stored and sent to the component. The debugger itself doesn’t have access to the event (state, session, etc), it makes a backend request to fetch the complete event.

Also, when you have [object Object], this means that your object was converted to that text, and it’s impossible to get the object, even with json.parse.

@allardy Thanks for looking into my issue.

I am not using the Call API skill, instead I created an action in my custom module which gets called, and assigns response to session.response and this session.response is sent back to InfaLinkPreview custom component (please check attached js & jsx code above), but here this.props.text is always "[Object Object]"

Can you please look into InfaLinkPreview.jsx & infa-link-preview.js file and below diagram, where i am going wrong?

Update

Hack way that worked is by making changes to below 2 files, but it would be great if you can help me get this working in proper way.

Changes in callServerApi.js action

session.response = JSON.stringify(response.data);

Changes in InfaLinkPreview.jsx view

contentArray = JSON.parse(this.props.text.replace(/&quot;/g, '"').replace(/&#x2F;/g, '/'));

Sample this.props.text

[{&quot;answer&quot;:{&quot;1&quot;:{&quot;content....}}}]

@abhisheksimon I think you are just using the wrong property. this.props.text will not contain your object, it will be converted to a string.
When you send your component payload, you need to include your object, ex:

{
	type: 'custom',
	module: 'custom-component',
	component: 'InfaLinkPreview',
	text: data.text,
        response: { someObjectWithMyResponse },
        someotherstuff: { anything: 'somestuff' }
  }

Then, in your custom component, you can access it with this.props.response, or this.props.someotherstuff, or any other property that you send.

Does that work for you ?

1 Like

Thanks, so I did below changes and it worked

{
	type: 'custom',
	module: 'custom-component',
	component: 'InfaLinkPreview',
	text: data.text,
        response: {
               data
        }
  }

and

contentArray = JSON.parse(this.props.response.data.session.response)

@abhisheksimon Good news ! I think you don’t even have to parse it. When you send a message to the chat user, the payload is stringified automatically before being stored in the database, and it is parsed when fetched