# Find and call components and plugins: FIND, COMPONENTS, SETTER, EXE, TAPI, MIDDLEWARE and ADAPT

> Look for the components of the page by name or path, call a method of several components at once, call functions by name, use two API addresses with TAPI and PIPE, run middleware before a route and replace the markers of a text.

Framework: jcomponent20
Product: jComponent 20 (jcomponent@20)
Language: en
Content-SHA256: ec11cb7c6892e8b6319d74607b472f92e3007b14b67d22fac5d5035710d4f9c6
Snapshot: c0700e321579725c5cf4f5ace1ad7d2866d1b4f93c24a63c0b41b6b7998e976c
Sources: jcomponent20@3fedd009a277f50fddc608b97afbec553b67c51b
Review: not-recorded

- `FIND(selector, [all])` returns a component that is ready: `'notice'` is its **name**, `'.msg'` its **path** (it matches the paths that contain it) and `'#id'` its id; with `all` set to `true` it returns the list. `COMPONENTS(path)` returns the list of the ready components whose path is under `path`; the flags of a path filter it (`'msg @visible'`).
- `SETTER('name/method', a, b, c, d)` calls `method` of **every** ready component with that name (`'.path/method'` for a path, `'#id/method'` for an id, `'*/method'` for all of them). A name that is not loaded yet is loaded first (a lazy component). `ASETTER(...)` does not call it: it returns a function that will.
- `EXE(name, a, b, c, d)` (the same as `EXEC()`) calls what the name says: `'plugin/method'` a method of a plugin, `'function'` a global function, or a path in the state that holds a function (`'FUNC.save'`). `SEEX(name, value)` is the same, but when the name is not a function it **sets** the path to `value`.
- `TAPI(name, data, callback)` is `API(DEF.api, ...)` and `PIPE(name, data, callback)` is `API(DEF.pipe, ...)`: two addresses of endpoints that you set once in `DEF.api` and `DEF.pipe`.
- `MIDDLEWARE(name, function(next) {})` registers a function that runs before a route: it has to call `next()` to let it go on. A route asks for one (or more, separated by commas) as its third argument: `ROUTE('/path/', handler, 'name')`. `MIDDLEWARE(['a', 'b'], callback)` runs the middleware in order and then the callback; one that does not call `next()` stops the chain.
- `NEWUIBIND(element, path, config)` makes a `ui-bind` on an element from the code (the element does not need the attributes), and returns it.
- `ADAPT(path, id, text)` prepares the text of a component that comes from outside: it translates `@(...)`, replaces `~PATH~` and `CLASS` with the path and `~ID~` with the id, and puts the `path` in the `<ui-plugin>` tags that do not have one. `COMPILE` is the same function as `NOOP` in jComponent 20: it does nothing.
- The objects behind everything: `jComponent`, `Total`, `MAIN` and `M` are the same object (the engine: `M.components` is the list of the components, `M.version` the version), `W` is `window`, `DEF` the defaults, and `REPO`, `FUNC`, `TEMP` and `PLUGINS` are plain objects of yours: `FUNC` for functions that `EXE('FUNC.name')` can call, `TEMP` is emptied by jComponent when the page starts again.

```js definitions/math.js
NEWACTION('Math/add', {
	name: 'Add two numbers',
	input: '*a:Number, *b:Number',
	action: function($, model) {
		$.callback({ sum: model.a + model.b });
	}
});
```

```js controllers/api.js
exports.install = function() {
	ROUTE('API /api/ +math_add --> Math/add');
	ROUTE('API /pipe/ +math_add --> Math/add');
};
```

```html public/index.html
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8" />
	<title>jComponent</title>
	<link rel="stylesheet" href="//cdn.componentator.com/spa.min@20.css" />
	<script src="//cdn.componentator.com/spa.min@20.js"></script>
</head>
<body>
	<ui-component name="notice" path="msg"></ui-component>
	<ui-component name="notice" path="other"></ui-component>
	<ui-plugin path="shop"></ui-plugin>
	<p id="target">x</p>
	<script>

		COMPONENT('notice', function(self) {
			self.make = function() { self.element.html('<b></b>'); };
			self.say = function(text, extra) { self.find('b').text(text + (extra || '')); };
		});

		PLUGIN('shop', function(exports) {
			exports.hello = function(a) { window.shoplog = 'hello ' + a; };
		});

		window.globalfn = function(a, b) { window.globallog = [a, b]; };
		FUNC.local = function(a) { window.funclog = a; };

		DEF.api = '/api/';
		DEF.pipe = '/pipe/';

	</script>
</body>
</html>
```
