template-query-object v2.0.3
╔╦╗┌─┐┌┬┐┌─┐┬ ┌─┐┌┬┐┌─┐ ╔═╗ ┬ ┬┌─┐┬─┐┬ ┬ ╔═╗┌┐ ┬┌─┐┌─┐┌┬┐
║ ├┤ │││├─┘│ ├─┤ │ ├┤ ║═╬╗│ │├┤ ├┬┘└┬┘ ║ ║├┴┐ │├┤ │ │
╩ └─┘┴ ┴┴ ┴─┘┴ ┴ ┴ └─┘ ╚═╝╚└─┘└─┘┴└─ ┴ ╚═╝└─┘└┘└─┘└─┘ ┴
(Ascii-art generated by patorjk.com)
Part of the Neo4J Line of Packages
isomorphic-node
^
|
+
isomorphic-cypher <--+ template-query-object
^ ^
| |
| +
| + neo4j-query-object
+ |
simple-neo4j <------+ neo4j-parser
|
+ cypher-tools
ascii-chart generated by asciiflow.com
Upgrade to 2.0
2.0 brings in a lot of big changes and consequently breaks support with pre 2.0 versions. If you have version 1.x or before make sure to read UPGRADE-2.0.md. Essentially callbacks were removed in favor of promises which required many alterations to the existing class.
About
This is a class who is designed to hold one instance per query. It self manages
a promise along with the query itself and various other data. Its designed to
store this query and other data until the query is processed and result received
in which case you simply issue the promise via issuePromise
providing any
errors and results whereby the class will properly resolve or reject the
promise with the result obj.
In addition to that, this class additionally offers sophisticated templating features powered by lodash's template function. Below I give a quick rundown on how to leverage the template functionality which seamlessly works in the background so you don't even have to think about it.
Seamless templates
You can just forget about the templating functionality all-together, it works in the background and only when needed. Here we simply provide a query without leveraging any templating functionality.
obj.queryTemplate = 'return "World"';
obj.query === 'return "World"';
You save the query's template to queryTemplate
, when getting query
it will return the compiled template. In this case, of course, we're not
leveraging any template features but lets begin using some of the features.
query is writable
Thanks to some Javascript magic, you can certainly write to query
if
you want to. Since query
is read-only, writing to it actually just writes
to queryTemplate so it can be shorter and perhaps easier to remember.
Just keep in mind, if you get in a habit of writing to query as a shorter alias, don't forget that reading from it will always return the compiled template.
obj.query = 'return "World"';
obj.query === 'return "World"';
Basic variables
To insert a variable into a template, simply use double curly braces like so
{{var_name_here}}
. All variables will read from the parameters.
obj.queryTemplate = 'return "{{hello}}"';
obj.localParams.hello = "world";
obj.query === 'return "World"'
// Very simple and easy
As mentioned above, you can shortcut to query
instead of queryTemplate
as
long as you keep in mind that reading from query will always return the compiled
template
// Here I use obj.query instead of obj.queryTemplate
// for convenience
obj.query = 'return "{{hello}}"';
obj.localParams.hello = "world";
// Just remember getting query will always return the compiled template
obj.query === 'return "World"'
Global and Local Variables
There are in actuality 2 variable scopes, global and local. Both are completely optional and either can be used, but the global scope was created with the intention of allowing an object outside the class to share variables among all instances of this class, of course what's assigned to it is entirely up to you.
With this in mind, if you choose to use both, local variables with the same name as the global variables will shadow global variables as to be expected.
So here's a quick breakdown
// Create some global variables for both instances
var globalParams = {
color: "red",
fruit: "apple"
};
// Assign the global parameters
obj1.globalParams = globalParams;
obj2.globalParams = globalParams;
// Tell instance 1 to override color
obj1.localParams.color = "green";
// Create the query template
obj1.queryTemplate = 'return "{{fruit}} is {{color}}"'
obj2.queryTemplate = 'return "{{fruit}} is {{color}}"'
obj1.query === 'return "apple is green"'
obj2.query === 'return "apple is red"'
The template always reflects the latest value
If the local or global variables change at any point in time, the end template will always reflect the newest value, this makes it very convenience and once again allows you to completely forget about the templating system even being there.
obj.localParams.hello = "world";
obj.queryTemplate = 'return "{{hello}}"';
obj.query === 'return "World"';
obj.localParams.hello = "New York!";
obj.query === 'return "New York!"';
parameters === localParams and globalParams
There is a parameters variable that represents both variables, local and global, and as usual local will shadow global if conflicts occur. This is the variable used when compiling templates and also when transmitting the query to the database.
As a result its read-only but, like with the query
variable, you can write to
it and it will instead alias to localParams
. This is provided for convenience
but is optional and up to you.
Example showing this
// Set a local and global variable
obj.localParams.color = "red";
obj.globalParams.fruit = "apple";
// Getting parameters shows both
// obj.parameters === {
// color: "red",
// fruit: "apple"
// }
// We make use of setting the read-only parameters variable which is
// a convenience alias of setting localParams
// Please note 2 things, a) We can only set the whole object at one time
// when doing this and b) when getting parameters it will always get both
// local and global
obj.parameters = {color2: "green"};
// This is shown here
// obj.parameters === {
// color2: "green",
// fruit: "apple"
// }
Escaping
Another feature of the template system is the fact that you can escape any
variable. To escape, use triple curly braces like so {{{var_name_here}}}
.
obj.localParams.hello = "<b>world</b>";
obj.queryTemplate = 'return "{{{hello}}}"';
// Spaces were added after ampersand because it caused rendering problems
// on web pages
obj.query === 'return "& lt;b& gt;world& lt;/b& gt;"';
And then theres partials
Partials are a neat little bit that allows you to write re-usable bits of
templates to sprinkle on your query. You include them in your template like
a normal variable but under the partials
property. Finally, only the partials
you reference in your query will be compiled, all others will be ignored.
obj.localParams.hello = "world";
obj.partials.getHello = 'return "{{hello}}"'
obj.queryTemplate = '{{partials.getHello}}';
obj.query === 'return "World"';
Couple of things to note, partials cannot include other partials, they're like completely isolated templates on their own. Also, as a general note, partials are compiled first before templates and inserted in as-is once compiled into the template.
Only a means for storage
This class does not contain any code for calling any database nor does it contain any code for parsing any result from the database. It's merely a storage object for code that does do those tasks to use making things much easier.
Generic but Neo4J-Feel
Technically this class can be used for anything, not just Neo4J. In fact it doesn't even have to be used for a query. But, despite this, it has the look and feel of the Neo4J-Line - A line of packages that are separate but work together to form the Neo4J system of packages.
For example in this class you'll see properties like raw
, parameters
,
first-value
, etc... These are generic to any kind of implementation and
don't have to be used but they're inspired from the needs of the other packages
in the Nei4J line so they're going to have that feel to them.
This package is solid
This package is actively tested with Jasmine and thoroughly documented throughout. It also contains complete JSDoc comments and full online JSDoc generated documentation.
Do you like this package or have an issue?
If this package has helped you I encourage you to follow it, give it a star, or fork it on github. If you have any ideas, suggestions, issues, or ways to improve upon it then let us know over at github by filing an issue.
Contributions are also encouraged and the CONTRIBUTING.md file shows all the details on development and how to contribute back but its mostly just commit changes and send a pull request.
This project is licensed Apache 2.0
http://www.apache.org/licenses/LICENSE-2.0.txt
Run it in your browser
Thanks to TonicDev, you now have a way to run this package right in your browser to test it out. If your on the NPM site you can see the TonicDev link on the right-hand side, otherwise you can always go to the link below.
TonicDev will load up a preset example we provide that you can play around with to get a feel for this package.
https://tonicdev.com/npm/template-query-object
How to develop
To develop, git clone
this repository and npm install
to install the
development dependencies. Make sure to run npm run build
when
needed which will test & compile ES6/7 to ES5 and re-generate the docs.
You can run those individually if you want with npm run docs
and
npm run compile
. To auto-copy over docs from master to gh-pages run
npm run pages
before committing and pushing.
For testing, just run npm run test
If you want to contribute back read the CONTRIBUTING.md
file.
Documentation
Detailed documentation exists for this package, it should already by viewable on clone. Feel free to look through it for any questions you may have. The source code is also heavily documented if you want to look through it as well for answers.
Online docs exist here http://junestoolbox.github.io/template-query-object/docs
Whats New
Check out the CHANGELOG.md file for latest changes and updates