{"id":21207159,"url":"https://github.com/hansottowirtz/elpong-js","last_synced_at":"2026-05-08T04:03:56.346Z","repository":{"id":57222663,"uuid":"61836474","full_name":"hansottowirtz/elpong-js","owner":"hansottowirtz","description":"Elpong for Javascript","archived":false,"fork":false,"pushed_at":"2018-09-05T17:40:26.000Z","size":9510,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-08T20:41:53.412Z","etag":null,"topics":["elpong","javascript","json-api","restful","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hansottowirtz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-06-23T21:00:09.000Z","updated_at":"2018-09-05T07:29:52.000Z","dependencies_parsed_at":"2022-09-02T02:50:23.123Z","dependency_job_id":null,"html_url":"https://github.com/hansottowirtz/elpong-js","commit_stats":null,"previous_names":["hansottowirtz/httpong-js"],"tags_count":21,"template":false,"template_full_name":null,"purl":"pkg:github/hansottowirtz/elpong-js","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hansottowirtz%2Felpong-js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hansottowirtz%2Felpong-js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hansottowirtz%2Felpong-js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hansottowirtz%2Felpong-js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hansottowirtz","download_url":"https://codeload.github.com/hansottowirtz/elpong-js/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hansottowirtz%2Felpong-js/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264357373,"owners_count":23595583,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elpong","javascript","json-api","restful","typescript"],"created_at":"2024-11-20T20:57:58.471Z","updated_at":"2025-12-12T05:47:10.762Z","avatar_url":"https://github.com/hansottowirtz.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Elpong for Javascript\n\n[![Build Status](https://travis-ci.org/hansottowirtz/elpong-js.svg?branch=master)](https://travis-ci.org/hansottowirtz/elpong-js)\n\n[![Sauce Test Status](https://saucelabs.com/browser-matrix/hansottowirtz.svg)](https://saucelabs.com/u/hansottowirtz)\n\n### If you don't understand the basics of Elpong, please read the first lines of [the spec][spec].\n\n### Although this is a draft, everything is tested and it should work in most modern browsers.\n\n## Getting started\n\n```bash\nnpm install elpong\n```\n\nUsing ES6 modules, Typescript or bundlers like Webpack is recommended:\n\n```javascript\nimport elpong, { Scheme, Element, Collection } from 'elpong';\n```\n\n```javascript\nconst elpong = require('elpong').default;\n```\n\n```html\n\u003cscript src=\"/scripts/elpong/dist/elpong.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n  elpong = elpong.default;\n\u003c/script\u003e\n```\n\n```javascript\n// Choose one of these:\nelpong.setAjax(window.fetch, 'fetch') // built-in in modern browsers\nelpong.setAjax($http, 'angularjs') // if you use AngularJS\nelpong.setAjax($.ajax, 'jquery') // if you use jQuery\nelpong.setAjax(http, 'angular') // if you use Angular, http: instance of Http or HttpClient\n\nelpong.enableAutoload(); // when using preloading\n// or\nvar scheme = elpong.add(scheme_config); // if you have the scheme in javascript\n\nscheme.setApiUrl('/api');\nvar pigs = scheme.select('pigs'); // select the pigs collection\n\nvar promise = pigs.actions.getAll(); // sends a GET to /api/pigs\npromise.then(function(response) {\n  for (pig in pigs.array()) {\n    alert('Received pig ' + pig.fields.name);\n  }\n})\n```\n\nAlternatively, you can use the `AjaxAdapterType` enum in Typescript:\n\n```javascript\nelpong.setAjax(window.fetch, AjaxAdapterType.Fetch);\n```\n\n## Schemes\n\nYou can create a scheme in two ways:\n\n`elpong.add(scheme_config)`\n\nor by preloading it, see [Preloading](#preloading)\n\nA scheme can be retrieved with `elpong.get(scheme_name)`\n\n## Collections\n\nWhen a scheme is created, it immediately creates the defined collections.\n\nThey can be retrieved with `scheme.select(collection_name)`\n\nYou can get an array of the elements in a collection with `collection.array()`\n\nFinding a specific object can be done with: `collection.find(id)` (if `id` is the selector),\nor `collection.findBy({name: name})`.\nIf you want to search for multiple elements with that name,\nuse `collection.findBy({name: name}, {multiple: true})`.\n\nTo load data into the collection, you can use `collection.actions.getAll()`,\nor `collection.actions.getOne(id)`. To preload it, see [Preloading](#preloading)\n\nIf you are using Rails, check out [this library][rails].\n\nTo make a new element, use `collection.build({name: 'Bob'})`.\u003cbr/\u003e\nThis element will be stored in the `new_elements` array, and when it is\n`POST`ed, and thus gets a selector value (`id` gets a value), it will end\nup in the `elements` object.\n\nYou shouldn't access the `new_elements` and `elements` attributes directly,\njust use `array()` or `array({without_new: true})` for that.\n\n#### Collection actions\n\nYou can execute collection actions with the `actions` key.\u003cbr/\u003e\nThe built in ones are `getOne` and `getAll`.\n\n## Elements\n\n#### Fields\n\nFields can be accessed through the `fields` key.\n\nExample:\n```javascript\npig.fields.name;\n```\n\n#### Actions\n\nYou can execute actions on the `actions` key. There are four built in ones:\n\n`get`: Sends a GET and updates the fields, overwriting the original fields.\n\n`post`: Sends a POST to the collection url. Should only be called if the\nelement is new, because it assigns a selector to the element.\n(The server should save it in some database, and thus it gets an id)\n\n`put`: Sends a PUT with the new data, and expects the same data sent back,\nor otherwise small updates.\n\n`delete`: Sends a DELETE, which should remove the element from the server,\nbut does not delete the element from the collection on the client side.\nUse `remove` to do that.\n\nAll actions accept params to be passed in the url.\n\nExample:\n```javascript\nvar pig = pigs.build();\npig.actions.post(); // saves the pig, pig gets an id\npig.actions.get();\npig.actions.put();\npig.actions.delete();\n\npig.actions.oink(); // sends a PUT to /api/pigs/8/oink\npig.actions.oink({params: {loud: true}}); // sends a PUT to /api/pigs/8/oink?load=true\n```\n\nActions and collection actions (e.g. `getAll()`) return a promise that returns\nthe response object.\n\n#### Relations\n\nYou can find other elements on the `relations` key.\n\nExample:\n```javascript\nhuman.relations.pigs();\npig.relations.boss();\n```\n\n#### Other functions\n\n`remove`: Triggers a `delete` on the element and removes it from the collection if it is saved.\nIf it is new, it is just removed from the collection on the client side.\nIn both cases, it returns a promise.\n\n`isNew`: Checks if the element has a selector value.\n\n#### Embedded collections and elements\n\nCan be accessed through their relations.\n\n#### Snapshots\n\nUnder the `snapshots` key:\n\n`make(tag)`: Makes a snapshot of the fields and returns a snapshot object,\nwith a `tag`, `time`, `data` and `revert` key.\nIf you call `revert`, the element fields will revert themselves to that snapshot.\n\n`undo(tag_or_steps)`:\n- When passed in a tag, will revert itself to the\nlast snapshot with that tag. The snapshot with tag `creation` is made after\n`build`. Snapshots with tags \u003ccode\u003ebefore_\u003ci\u003eaction\u003c/i\u003e\u003c/code\u003e and \u003ccode\u003eafter_\u003ci\u003eaction\u003c/i\u003e\u003c/code\u003e\nare made after those actions, like `before_get` and `after_put`.\n- When passed in a number, it will revert itself *n* steps. No argument equals 0 steps, which\nreverts itself to the last snapshot.\n\n`isPersisted()`: Compares fields with the `lastPersisted()`.\nNote: when one of the fields is an object, it will\nreturn `true` when changing the keys of that object, because the object reference\nis the same. The fields are compared with `===`. Returns `false` if the element\nis new.\n\n`lastPersisted()`: Gets last snapshot where the tag is `after_get`, `after_post`\n,`after_put` or `creation`.\n\n`last()`: Gets last snapshot\n\n`lastWithTag(tag)`: Gets last snapshot where the tag matches the tag string\nor regex.\n\nYou can loop through snapshots with the `list` key.\n\n```javascript\nelement.lastPersisted().revert() // reverts the fields to the last persisted snapshot\n```\n\n#### Merging\n\nIf data is received in another way, like with WebSockets, it can be merged with\nthe other data using `merge`.\n\n### Preloading\n\nTo preload a scheme, create a meta tag with\n`name=\"elpong-scheme\"`, \u003ccode\u003escheme=\u003ci\u003escheme_name\u003c/i\u003e\u003c/code\u003e and \u003ccode\u003econtent=\u003ci\u003escheme\u003c/i\u003e\u003c/code\u003e.\u003cbr/\u003e\n*scheme* is the JSON scheme.\n\nTo preload data, create a meta tag with\n`name=\"elpong-collection\"`, \u003ccode\u003escheme=\u003ci\u003escheme_name\u003c/i\u003e\u003c/code\u003e, \u003ccode\u003econtent=\u003ci\u003eelements\u003c/i\u003e\u003c/code\u003e and \u003ccode\u003ecollection=\u003ci\u003ecollection_name\u003c/i\u003e\u003c/code\u003e.\u003cbr/\u003e\n*elements* is the same JSON data the API would return.\n\nTo preload a single element, create a meta tag with\n`name=\"elpong-element\"`, \u003ccode\u003escheme=\u003ci\u003escheme_name\u003c/i\u003e\u003c/code\u003e, \u003ccode\u003econtent=\u003ci\u003eelement\u003c/i\u003e\u003c/code\u003e and \u003ccode\u003ecollection=\u003ci\u003ecollection_name\u003c/i\u003e\u003c/code\u003e.\n\nThen you can use `elpong.load()` and `collection.load()` to load schemes and\ncollections, respectively, or you can use `elpong.enableAutoload()` and it will take\ncare of it when it reads the scheme. Make sure to put the `meta` tags *above*\nthe `script` tags when you do this. `elpong.enableAutoload()` might give some problems\nbecause it is synchronous.\n\n### Examples\n\n###### Animal Farm\n[Scheme](../master/test/fixtures/animal-farm/scheme.json5)\n[Usage](../master/test/animal_farm_spec.coffee)\n\n###### Pulser\n[Scheme](../master/test/fixtures/pulser/scheme.json5)\n[Usage](../master/test/pulser_spec.coffee)\n\n### Setting an ajax function\n\nThe ajax function expects one argument object with `url`, `method`, `data` and\n`headers` keys.\u003cbr/\u003e\nIt should return a Promise-like object that catches when the response status is\nnot between 200 and 299, and on other network errors.\u003cbr/\u003e\nThe `then` and `catch` functions should return a response object with a\n`data` key, that holds the parsed JSON object.\n`$http`, `Http`, and `jQuery.ajax` are supported out of the box.\u003cbr/\u003e\nIf you don't work with AngularJS, Angular, or jQuery, you can use [window.fetch](fetch).\n\n```javascript\nelpong.setAjax(window.fetch, 'fetch') // built-in in modern browsers\nelpong.setAjax($http, 'angularjs') // if you use AngularJS\nelpong.setAjax($.ajax, 'jquery') // if you use jQuery\nelpong.setAjax(http, 'angular') // if you use Angular, http: instance of Http or HttpClient\n```\n\n### Contributing\n\nYes please!\n\nFork it, then do something like this:\n```bash\ngit clone https://github.com/\u003cyou\u003e/elpong-js\ncd elpong-js\ngit checkout -b add-a-feature\nnpm install -g gulp-cli coffeescript typescript\nnpm install\ngulp test\n```\nCheck the `gulpfile.js` for other tasks.\u003cbr/\u003e\nMake pull requests when you think your feature should be merged or\nwhen you want feedback. Issues are very welcome too!\n\n[spec]: https://github.com/hansottowirtz/elpong/blob/master/SPEC.md\n[angularjs]: https://github.com/hansottowirtz/elpong-angularjs\n[jquery]: https://github.com/hansottowirtz/elpong-jquery\n[rails]: https://github.com/hansottowirtz/elpong-rails\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhansottowirtz%2Felpong-js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhansottowirtz%2Felpong-js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhansottowirtz%2Felpong-js/lists"}