How do I send Params to my runtime action? | Community
Skip to main content
prashantonkar
Level 4
July 14, 2020
Solved

How do I send Params to my runtime action?

  • July 14, 2020
  • 2 replies
  • 4275 views

I have created a Adobe IO runtime project based on firefly template. I have added Adobe Analytics API in my console.adobe.io. While creating the project thru AIO, it has created a sample action which fetches collections from adobe analytics.

 

Problem 1: When I open this app using localhost:9080, I get this error

 

in ForwardRef($f01f0d1066865f7027d77d32f5de6fe$var$Picker) (created by App)
    in ModalProvider (created by ForwardRef($bc3300334f45fd1ec62a173e70ad86$var$Provider))
    in I18nProvider (created by ForwardRef($bc3300334f45fd1ec62a173e70ad86$var$Provider))
    in ForwardRef($bc3300334f45fd1ec62a173e70ad86$var$Provider) (created by ForwardRef($d618213cd07bac427c632ce5c90d7$var$Form))
    in form (created by ForwardRef($d618213cd07bac427c632ce5c90d7$var$Form))
    in ForwardRef($d618213cd07bac427c632ce5c90d7$var$Form) (created by App)
    in div (created by ForwardRef($f9fee2c1db386bde8f28b36a814d1eb2$var$Flex))
    in ForwardRef($f9fee2c1db386bde8f28b36a814d1eb2$var$Flex) (created by App)
    in div (created by ForwardRef($f9fee2c1db386bde8f28b36a814d1eb2$var$Flex))
    in ForwardRef($f9fee2c1db386bde8f28b36a814d1eb2$var$Flex) (created by App)
    in div (created by ForwardRef(ProviderWrapper))
    in ForwardRef(ProviderWrapper) (created by ForwardRef($bc3300334f45fd1ec62a173e70ad86$var$Provider))
    in ModalProvider (created by ForwardRef($bc3300334f45fd1ec62a173e70ad86$var$Provider))
    in I18nProvider (created by ForwardRef($bc3300334f45fd1ec62a173e70ad86$var$Provider))
    in ForwardRef($bc3300334f45fd1ec62a173e70ad86$var$Provider) (created by App)
    in ErrorBoundary (created by App)
    in App
Cannot destructure property 'scale' of '(0 , _provider.useProvider)(...)' as it is null.

 

Problem 2: When I call the action from CURL I get this error 

 

400: missing parameter(s) 'companyId'

 

 

I understand that I need to send company Id. But what I am not understanding is how to send it. Here is what i tried so far:

1. sent it as a header - 400: missing parameter(s) 'companyId'

2. sent it in json body - Request defines parameters that are not allowed (e.g., reserved properties)

3. sent it as query param.-Request defines parameters that are not allowed (e.g., reserved properties)

 

None of these have worked so far. I do not see any documentation on how to send this parameter. Please help.

 

EDIT: here is the app.js. I havent made any changes to these files.

 

/* * <license header> */ // react imports import React from 'react' import PropTypes from 'prop-types' import ErrorBoundary from 'react-error-boundary' // react spectrum components import { Provider } from '@react-spectrum/provider' import { theme } from '@react-spectrum/theme-default' import { Button } from '@react-spectrum/button' import { TextField } from '@react-spectrum/textfield' import { Link } from '@react-spectrum/link' import { Picker, Item } from '@react-spectrum/picker' import { Form } from '@react-spectrum/form' import { Flex } from '@react-spectrum/layout' import { ProgressCircle } from '@react-spectrum/progress' import { Heading, Text } from '@react-spectrum/text'; // local imports import './App.css' import { actionWebInvoke } from './utils' import actions from './config.json' /* Here is your entry point React Component, this class has access to the Adobe Experience Cloud Shell runtime object */ export default class App extends React.Component { constructor (props) { super(props) // error handler on UI rendering failure this.onError = (e, componentStack) => {} // component to show if UI fails rendering this.fallbackComponent = ({ componentStack, error }) => ( <React.Fragment> <h1 style={{ textAlign: 'center', marginTop: '20px' }}>Something went wrong :(</h1> <pre>{ componentStack + '\n' + error.message }</pre> </React.Fragment> ) this.state = { actionSelected: null, actionResponse: null, actionResponseError: null, actionHeaders: null, actionHeadersValid: null, actionParams: null, actionParamsValid: null, actionInvokeInProgress: false } console.log('runtime object:', this.props.runtime) console.log('ims object:', this.props.ims) // use exc runtime event handlers // respond to configuration change events (e.g. user switches org) this.props.runtime.on('configuration', ({ imsOrg, imsToken, locale }) => { console.log('configuration change', { imsOrg, imsToken, locale }) }) // respond to history change events this.props.runtime.on('history', ({ type, path }) => { console.log('history change', { type, path }) }) } static get propTypes () { return { runtime: PropTypes.any, ims: PropTypes.any } } // parses a JSON input and adds it to the state async setJSONInput (input, stateJSON, stateValid) { let content let validStr = null if (input) { try { content = JSON.parse(input) validStr = 'valid' } catch (e) { content = null validStr = 'invalid' } } this.setState({ [stateJSON]: content, [stateValid]: validStr }) } // invokes a the selected backend actions with input headers and params async invokeAction () { this.setState({ actionInvokeInProgress: true }) const action = this.state.actionSelected const headers = this.state.actionHeaders || {} const params = this.state.actionParams || {} // all headers to lowercase Object.keys(headers).forEach(h => { const lowercase = h.toLowerCase() if (lowercase !== h) { headers[lowercase] = headers[h] headers[h] = undefined delete headers[h] } }) // set the authorization header and org from the ims props object if (this.props.ims.token && !headers.authorization) { headers.authorization = 'Bearer ' + this.props.ims.token } if (this.props.ims.org && !headers['x-gw-ims-org-id']) { headers['x-gw-ims-org-id'] = this.props.ims.org } try { // invoke backend action const actionResponse = await actionWebInvoke(action, headers, params) // store the response this.setState({ actionResponse, actionResponseError: null, actionInvokeInProgress: false }) console.log(`Response from ${action}:`, actionResponse) } catch (e) { // log and store any error message console.error(e) this.setState({ actionResponse: null, actionResponseError: e.message, actionInvokeInProgress: false }) } } render () { return ( // ErrorBoundary wraps child components to handle eventual rendering errors <ErrorBoundary onError={ this.onError } FallbackComponent={ this.fallbackComponent } > <Provider UNSAFE_className='provider' theme={ theme }> <Flex UNSAFE_className='main'> <Heading UNSAFE_className='main-title'>Welcome to OnkarAnalyticsIO!</Heading> <Flex UNSAFE_className='main-actions'> <h3 className='actions-title'>Run your application backend actions</h3> { Object.keys(actions).length > 0 && <Form UNSAFE_className='actions-form' necessityIndicator='label'> <Picker placeholder='select an action' aria-label='select an action' items={ Object.keys(actions).map(k => ({ name: k })) } itemKey='name' onSelectionChange={ name => this.setState({ actionSelected: name, actionResponseError: null, actionResponse: null }) }> { item => <Item key={item.name}>{ item.name }</Item> } </Picker> <TextField label='headers' placeholder='{ "key": "value" }' validationState={ this.state.actionHeadersValid } onChange={ input => this.setJSONInput(input, 'actionHeaders', 'actionHeadersValid' ) }/> <TextField label='params' placeholder='{ "key": "value" }' validationState={ this.state.actionParamsValid } onChange={ input => this.setJSONInput(input, 'actionParams', 'actionParamsValid' ) }/> <Flex UNSAFE_className='actions-invoke'> <Button UNSAFE_className='actions-invoke-button' variant='primary' onPress={ this.invokeAction.bind(this) } isDisabled={ !this.state.actionSelected }> Invoke </Button> <ProgressCircle UNSAFE_className='actions-invoke-progress' aria-label='loading' isIndeterminate isHidden={ !this.state.actionInvokeInProgress }/> </Flex> </Form> } { Object.keys(actions).length === 0 && <Text>You have no actions !</Text> } { this.state.actionResponseError && <Text UNSAFE_className='actions-invoke-error'> Failure! See the error in your browser console. </Text> } { !this.state.actionError && this.state.actionResponse && <Text UNSAFE_className='actions-invoke-success'> Success! See the response content in your browser console. </Text> } </Flex> <Flex UNSAFE_className='main-doc'> <h3 className='doc-title'>Useful documentation for your app</h3> <Link UNSAFE_className='doc-item'> <a href='https://github.com/AdobeDocs/project-firefly/blob/master/README.md#project-firefly-developer-guide' target='_blank'> Firefly Apps </a> </Link> <Link UNSAFE_className='doc-item'> <a href='https://github.com/adobe/aio-sdk#adobeaio-sdk' target='_blank'> Adobe I/O SDK </a> </Link> <Link UNSAFE_className='doc-item'> <a href='https://adobedocs.github.io/adobeio-runtime/' target='_blank'> Adobe I/O Runtime </a> </Link> <Link UNSAFE_className='doc-item'> <a href='https://react-spectrum.adobe.com/react-spectrum/index.html' target='_blank'> React Spectrum </a> </Link> </Flex> </Flex> </Provider> </ErrorBoundary> ) } }

 

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.
Best answer by duynguyen_adobe

Problem 1: please try giving all the `@react-spectrum` dependencies version "3.0.1", then `npm install` and re-run your app. This is the tracking issue for the record: https://github.com/adobe/aio-cli/issues/201.

Problem 2: if you selected "Adobe Analytics" from the template with `aio app init`, your .env file would have a variable called `ANALYTICS_COMPANY_ID` commented out. Please set your company ID there, uncomment (by removing the hash "#"), and then re-run the app. The env var is picked up by the app according to the mapping in manifest.yml.

 

2 replies

Adobe Employee
July 14, 2020

Hi there - To troubleshoot problem 1, could you please share your code in web-src/src/App.js ? Did you modify anything in the web-src/ folder?

 

duynguyen_adobeAdobe EmployeeAccepted solution
Adobe Employee
July 14, 2020

Problem 1: please try giving all the `@react-spectrum` dependencies version "3.0.1", then `npm install` and re-run your app. This is the tracking issue for the record: https://github.com/adobe/aio-cli/issues/201.

Problem 2: if you selected "Adobe Analytics" from the template with `aio app init`, your .env file would have a variable called `ANALYTICS_COMPANY_ID` commented out. Please set your company ID there, uncomment (by removing the hash "#"), and then re-run the app. The env var is picked up by the app according to the mapping in manifest.yml.

 

Adobe Employee
July 15, 2020

If you leave the default settings from the template, meaning "require-adobe-auth" is set to true, the Runtime action expects the bearer token in the authorization header. You could find more details here: https://github.com/AdobeDocs/project-firefly/blob/master/guides/security_overview.md.

The IMS token is generated for the API service you work with (Analytics). The Runtime action only validates that it belongs to the right org and is valid to access the service. Hence in AEM particularly, you would use the IMS config for Analytics (if available), or add it to your AEM instance.