Skip to main content

The server.js

Add some logic​

We can create components which provide static content. In that case our view could look like this:

<div>hello world</div>

and we don't need to modify any other files.

But when we want to provide some additional logic in our view:

<div>hello {{name}}</div>

we have to modify our server.js (model provider).

In the given example, we want to pass name parameter to our view. To achieve this goal, we can modify server file in this way:

"use strict";

module.exports.data = function (context, callback) {
callback(null, {
name: "John",
});
};

The first parameter is used in case we want to fire an error and avoid the rendering.

The second parameter of the callback function is a view-model (JSON object) which is used by the view.

However, for more complicated operations we may need query parameters from component request. In this case we can use params property from context object (first parameter of our server function).

In our example we want to extract name parameter from the context object:

module.exports.data = function (context, callback) {
callback(null, {
name: context.params.name || "John",
});
};

To consume the component passing the name parameter we need to modify the reference link, e.g:

<oc-component
href="http://localhost:3030/hello-world?name=James"
></oc-component>

Context properties​

Context aggregates request data, and the registry's context. It consists of the following fields:

{
"acceptLanguage": [
{
"code": "en",
"region": "US",
"quality": 1
},
{
"code": "en",
"quality": 0.8
}
],
"baseUrl": "http://localhost:3030/",
"env": {
"name": "local"
},
"params": {
"name": "Johnny"
},
"renderComponent": [Function],
"renderComponents": [Function],
"requestHeaders": {
"host": "localhost:3000",
"connection": "keep-alive",
"accept": "application/vnd.oc.unrendered+json",
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36",
"content-type": "text/plain",
"referer": "http://localhost:3000/oc-client/0.28.5/~preview/",
"accept-encoding": "gzip, deflate, sdch",
"accept-language": "en-US,en;q=0.8",
},
"setEmptyResponse": [Function],
"setHeader": [Function],
"staticPath": "http://localhost:3030/hello-world/1.0.0/static/"
}
ParameterTypeDescription
acceptLanguagearray of objectsrepresents parsed accept-language part of the request header sorted by quality. More details here
baseUrlstringrepresents public registry base url. This is required when we want to nest components that are hosted in the same registry for client-side rendering
envobjectrepresents the registry environment variables. The registry's admin can share here arbitrary data
paramsobjectrepresents parameters extracted from the query string
pluginsarray of functionscustom functionalities that extend the registry. Note: if a component needs a plugin, it needs to be declared in the component's package.json
renderComponentfunctionNeeded to do server-side nested renderings. renderComponent API
renderComponentsfunctionNeeded to do server-side nested renderings. renderComponents API
requestHeadersobjectrepresents the original request headers. When component is rendered client side this will be what is sent from the browser, when rendered server side, using oc-client, this will contain whatever the client has been configured to forward
setEmptyResponsefunctionSets the response to be completely empty (included container and renderInfo). Recommended is to return it: return context.setEmptyResponse();
setHeaderfunctionNeeded to set custom headers. Signature is (name, value)
staticPathstringrepresents the path to static resources i.e. images, styles, javascript files. This is required to reference static resources to the view and already includes a final slash (this is relevant due to how S3 handles filePaths).

renderComponent API​

Signature: context.renderComponent(componentName [, options], callback)

ParameterTypeMandatoryDescription
componentNamestringyesThe component's name to be rendered. Needs to be hosted on the same registry
optionsobjectnoThe options
options.versionstringnoDefault '' (latest) - the version of the component to render
options.parametersobjectnoComponent's parameters
options.headersobjectnoHeaders to be injected to the nested component
callbackfunctionyesThe callback. Signature is callback(error, html)

renderComponents API​

Signature: context.renderComponents(components [, options], callback)

ParameterTypeMandatoryDescription
componentsarrayyesThe components to be rendered. Need to be hosted on the same registry
components[index].namestringyesThe component's name to be rendered
components[index].versionstringnoDefault '' (latest) - the version of the component to render
components[index].parametersobjectnoThe components' parameters
optionsobjectnoThe global options
options.parametersobjectnoComponents "global" parameters. If in need to render many components with the same parameters, they can be specified "globally" instead of in each component's "parameters" field
options.headersobjectnoHeaders to be forwarded to be injected to the nested components
callbackfunctionyesThe callback. Signature is callback(error, response). Response will be an array with a mix of strings of html (in case of success) and/or Error containing the details (in case of failure)

Add static resource to the component​

In this example an image (public/static_resource.png) will be our static resource.

Prepare package file​

First step is to prepare package.json file. It is necessary to add static property in oc.files object:

{
"name": "hello-world",
"description": "description of my hello-world component",
"version": "1.0.0",
"repository": "",
"oc": {
"files": {
"data": "server.js",
"template": {
"src": "template.html",
"type": "oc-template-handlebars"
},
"static": ["public"]
}
},
"devDependencies": {
"oc-template-handlebars-compiler": "6.0.8"
}
}

It is an array of names of directories. In the above example the public directory will be included inside the package.

Add image in the view template​

We can add image to the component view template using img tag in which src attribute is bound to img viewModel property.

<img src="{{path}}public/static_resource.png" />

Update server file​

To provide img parameter in our viewModel we need to update server.js. The important thing is we need to use context.staticPath to provide url to the static resources:

module.exports.data = function (context, callback) {
callback(null, {
path: context.staticPath,
});
};

Node.js dependencies on the server.js​

By default, require is not allowed on a server.js. This helps to keep components' logic clean and small. However, you can consume dependencies if the registry's owner agrees on making them available.

Local development​

When in a directory of components, list the dependency in the component's package.json and then start the watcher:

...
{
"dependencies": {
"underscore": ""
}
}
...

As soon as the watcher starts the dependency will be installed and it will be possible to require('underscore') inside a server.js.

Publishing​

When a dependency is used, during publishing, the registry may deny a component to be published if the dependency is not been vetted by the registry's owner.