├── .editorconfig ├── .ember-cli ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .npmignore ├── .template-lintrc.js ├── .travis.yml ├── .watchmanconfig ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE.md ├── MODULE_REPORT.md ├── README.md ├── addon ├── .gitkeep ├── mixins │ ├── autosubscribe.js │ └── query-params.js └── services │ └── params-relay.js ├── app ├── .gitkeep └── services │ └── params-relay.js ├── config ├── ember-try.js └── environment.js ├── ember-cli-build.js ├── index.js ├── package-lock.json ├── package.json ├── testem.js ├── tests ├── dummy │ ├── app │ │ ├── app.js │ │ ├── components │ │ │ └── .gitkeep │ │ ├── controllers │ │ │ ├── .gitkeep │ │ │ ├── application.js │ │ │ └── test.js │ │ ├── helpers │ │ │ └── .gitkeep │ │ ├── index.html │ │ ├── models │ │ │ └── .gitkeep │ │ ├── resolver.js │ │ ├── router.js │ │ ├── routes │ │ │ ├── .gitkeep │ │ │ ├── application.js │ │ │ └── test.js │ │ ├── styles │ │ │ └── app.css │ │ └── templates │ │ │ ├── application.hbs │ │ │ ├── components │ │ │ └── .gitkeep │ │ │ └── test.hbs │ ├── config │ │ ├── environment.js │ │ ├── optional-features.json │ │ └── targets.js │ └── public │ │ └── robots.txt ├── helpers │ └── .gitkeep ├── index.html ├── integration │ └── .gitkeep ├── test-helper.js └── unit │ ├── .gitkeep │ ├── mixins │ ├── autosubscribe-test.js │ └── query-params-test.js │ └── services │ └── params-relay-test.js └── vendor └── .gitkeep /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | 8 | [*] 9 | end_of_line = lf 10 | charset = utf-8 11 | trim_trailing_whitespace = true 12 | insert_final_newline = true 13 | indent_style = space 14 | indent_size = 2 15 | 16 | [*.hbs] 17 | insert_final_newline = false 18 | 19 | [*.{diff,md}] 20 | trim_trailing_whitespace = false 21 | -------------------------------------------------------------------------------- /.ember-cli: -------------------------------------------------------------------------------- 1 | { 2 | /** 3 | Ember CLI sends analytics information by default. The data is completely 4 | anonymous, but there are times when you might want to disable this behavior. 5 | 6 | Setting `disableAnalytics` to true will prevent any data from being sent. 7 | */ 8 | "disableAnalytics": false 9 | } 10 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | # unconventional js 2 | /blueprints/*/files/ 3 | /vendor/ 4 | 5 | # compiled output 6 | /dist/ 7 | /tmp/ 8 | 9 | # dependencies 10 | /bower_components/ 11 | /node_modules/ 12 | 13 | # misc 14 | /coverage/ 15 | !.* 16 | 17 | # ember-try 18 | /.node_modules.ember-try/ 19 | /bower.json.ember-try 20 | /package.json.ember-try 21 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parserOptions: { 4 | ecmaVersion: 2018, 5 | sourceType: 'module' 6 | }, 7 | plugins: [ 8 | 'ember' 9 | ], 10 | extends: [ 11 | 'eslint:recommended', 12 | 'plugin:ember/recommended' 13 | ], 14 | env: { 15 | browser: true 16 | }, 17 | rules: { 18 | }, 19 | overrides: [ 20 | // node files 21 | { 22 | files: [ 23 | '.eslintrc.js', 24 | '.template-lintrc.js', 25 | 'ember-cli-build.js', 26 | 'index.js', 27 | 'testem.js', 28 | 'blueprints/*/index.js', 29 | 'config/**/*.js', 30 | 'tests/dummy/config/**/*.js' 31 | ], 32 | excludedFiles: [ 33 | 'addon/**', 34 | 'addon-test-support/**', 35 | 'app/**', 36 | 'tests/dummy/app/**' 37 | ], 38 | parserOptions: { 39 | sourceType: 'script', 40 | ecmaVersion: 2015 41 | }, 42 | env: { 43 | browser: false, 44 | node: true 45 | }, 46 | plugins: ['node'], 47 | rules: Object.assign({}, require('eslint-plugin-node').configs.recommended.rules, { 48 | // add your custom rules and overrides for node files here 49 | }) 50 | } 51 | ] 52 | }; 53 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist/ 5 | /tmp/ 6 | 7 | # dependencies 8 | /bower_components/ 9 | /node_modules/ 10 | 11 | # misc 12 | /.env* 13 | /.pnp* 14 | /.sass-cache 15 | /connect.lock 16 | /coverage/ 17 | /libpeerconnection.log 18 | /npm-debug.log* 19 | /testem.log 20 | /yarn-error.log 21 | 22 | # ember-try 23 | /.node_modules.ember-try/ 24 | /bower.json.ember-try 25 | /package.json.ember-try 26 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist/ 3 | /tmp/ 4 | 5 | # dependencies 6 | /bower_components/ 7 | 8 | # misc 9 | /.bowerrc 10 | /.editorconfig 11 | /.ember-cli 12 | /.env* 13 | /.eslintignore 14 | /.eslintrc.js 15 | /.gitignore 16 | /.template-lintrc.js 17 | /.travis.yml 18 | /.watchmanconfig 19 | /bower.json 20 | /config/ember-try.js 21 | /CONTRIBUTING.md 22 | /ember-cli-build.js 23 | /testem.js 24 | /tests/ 25 | /yarn.lock 26 | .gitkeep 27 | 28 | # ember-try 29 | /.node_modules.ember-try/ 30 | /bower.json.ember-try 31 | /package.json.ember-try 32 | -------------------------------------------------------------------------------- /.template-lintrc.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | extends: 'recommended' 5 | }; 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: node_js 3 | node_js: 4 | # we recommend testing addons with the same minimum supported node version as Ember CLI 5 | # so that your addon works for all apps 6 | - "8" 7 | 8 | sudo: false 9 | dist: trusty 10 | 11 | addons: 12 | chrome: stable 13 | 14 | cache: 15 | directories: 16 | - $HOME/.npm 17 | 18 | env: 19 | global: 20 | # See https://git.io/vdao3 for details. 21 | - JOBS=1 22 | 23 | branches: 24 | only: 25 | - master 26 | # npm version tags 27 | - /^v\d+\.\d+\.\d+/ 28 | 29 | jobs: 30 | fail_fast: true 31 | allow_failures: 32 | - env: EMBER_TRY_SCENARIO=ember-canary 33 | 34 | include: 35 | # runs linting and tests with current locked deps 36 | 37 | - stage: "Tests" 38 | name: "Tests" 39 | script: 40 | - npm run lint:hbs 41 | - npm run lint:js 42 | - npm test 43 | 44 | # we recommend new addons test the current and previous LTS 45 | # as well as latest stable release (bonus points to beta/canary) 46 | - stage: "Additional Tests" 47 | env: EMBER_TRY_SCENARIO=ember-lts-2.18 48 | - env: EMBER_TRY_SCENARIO=ember-lts-3.4 49 | - env: EMBER_TRY_SCENARIO=ember-release 50 | - env: EMBER_TRY_SCENARIO=ember-beta 51 | - env: EMBER_TRY_SCENARIO=ember-canary 52 | - env: EMBER_TRY_SCENARIO=ember-default-with-jquery 53 | 54 | script: 55 | - node_modules/.bin/ember try:one $EMBER_TRY_SCENARIO 56 | -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | { 2 | "ignore_dirs": ["tmp", "dist"] 3 | } 4 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. 4 | 5 | ### [2.1.2](https://github.com/knownasilya/ember-query-params/compare/v2.1.1...v2.1.2) (2019-06-13) 6 | 7 | 8 | ### Bug Fixes 9 | 10 | * .match call on null ([#27](https://github.com/knownasilya/ember-query-params/issues/27)) ([f64a029](https://github.com/knownasilya/ember-query-params/commit/f64a029)) 11 | * codemods ([2ee2594](https://github.com/knownasilya/ember-query-params/commit/2ee2594)) 12 | * shorthand ([8784538](https://github.com/knownasilya/ember-query-params/commit/8784538)) 13 | * update ([9fc93e5](https://github.com/knownasilya/ember-query-params/commit/9fc93e5)) 14 | * update lockfile ([c3fe3d6](https://github.com/knownasilya/ember-query-params/commit/c3fe3d6)) 15 | 16 | 17 | 18 | ### [2.1.1](https://github.com/knownasilya/ember-query-params/compare/v2.1.0...v2.1.1) (2019-06-13) 19 | 20 | 21 | ### Bug Fixes 22 | 23 | * deserialization of array ([#26](https://github.com/knownasilya/ember-query-params/issues/26)) ([fa38cd5](https://github.com/knownasilya/ember-query-params/commit/fa38cd5)) 24 | * handle nulls in auto subscribe queryParamsDidchange ([#24](https://github.com/knownasilya/ember-query-params/issues/24)) ([437950f](https://github.com/knownasilya/ember-query-params/commit/437950f)) 25 | 26 | 27 | 28 | # Changelog 29 | 30 | ## v2.1.0 (5/10/2016) 31 | 32 | #### Fixes 33 | 34 | - Normalize string arrays 35 | - Don't set initial hash if there are params 36 | - Copy array values, so not changed by reference 37 | 38 | #### Features 39 | 40 | - `hasParams` method added. 41 | 42 | ## v2.0.4 (4/18/2016) 43 | 44 | #### Fixes 45 | 46 | - Prevent error if hash for `setParams` is `undefined` 47 | 48 | ## v2.0.3 (4/15/2016) 49 | 50 | #### Fixes 51 | 52 | - Compare array values for setParam handler calls (prevent SO) 53 | - Only send changed QPs from queryParamsDidChange action 54 | 55 | ## v2.0.2 (4/13/2016) 56 | 57 | #### Fixes 58 | 59 | - Don't call handlers if param value unchanged, resolves #16 60 | 61 | ## v2.0.1 (4/12/2016) 62 | 63 | #### Fixes 64 | 65 | - Fix duplicate sections in README 66 | 67 | ## v2.0.0 (4/12/2016) 68 | 69 | #### Breaking Changes 70 | 71 | - `AutoSubscribe` mixin is now for the route, and not the controller. See the README for new usage instructions. 72 | - Auto controller defaults are only setup if those params are not setup in the service yet. 73 | 74 | ## v1.3.0 (4/8/2016) 75 | 76 | #### Features 77 | 78 | - `setParams` - new method on the `paramsRelay` service which allows setting an object of keys/values as params. 79 | 80 | ## v1.2.0 (4/8/2016) 81 | 82 | #### Features 83 | 84 | - Auto set defaults on `autoSubscribe` 85 | 86 | ## v1.1.0 (4/8/2016) 87 | 88 | #### Features 89 | 90 | - Controller Mixin 91 | - Unsubscribe methods 92 | 93 | ## v1.0.5 (4/8/2016) 94 | 95 | #### Fixes 96 | 97 | - Remove use of `Map` so no polyfill is required 98 | 99 | ## v1.0.4 (4/7/2016) 100 | 101 | #### Fixes 102 | 103 | - Allow multiple map instances, fixes usage in tests 104 | 105 | ## v1.0.3 (4/7/2016) 106 | 107 | #### Fixes 108 | 109 | - Don't update callbacks if object destroyed. Thanks @rwjblue 110 | 111 | ## v1.0.2 (4/7/2016) 112 | 113 | #### Fixes 114 | 115 | - Add tests 116 | 117 | ## v1.0.1 (4/7/2016) 118 | 119 | #### Fixes 120 | 121 | - Readme updates 122 | 123 | ## v1.0.0 (4/7/2016) 124 | 125 | - Initial Release 126 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How To Contribute 2 | 3 | ## Installation 4 | 5 | * `git clone ` 6 | * `cd my-addon` 7 | * `npm install` 8 | 9 | ## Linting 10 | 11 | * `npm run lint:hbs` 12 | * `npm run lint:js` 13 | * `npm run lint:js -- --fix` 14 | 15 | ## Running tests 16 | 17 | * `ember test` – Runs the test suite on the current Ember version 18 | * `ember test --server` – Runs the test suite in "watch mode" 19 | * `ember try:each` – Runs the test suite against multiple Ember versions 20 | 21 | ## Running the dummy application 22 | 23 | * `ember serve` 24 | * Visit the dummy application at [http://localhost:4200](http://localhost:4200). 25 | 26 | For more information on using ember-cli, visit [https://ember-cli.com/](https://ember-cli.com/). 27 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2019 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /MODULE_REPORT.md: -------------------------------------------------------------------------------- 1 | ## Module Report 2 | ### Unknown Global 3 | 4 | **Global**: `Ember.inject` 5 | 6 | **Location**: `addon/mixins/autosubscribe.js` at line 3 7 | 8 | ```js 9 | import Ember from 'ember'; 10 | 11 | const { typeOf, inject } = Ember; 12 | const arrRegex = /^"?\[.*,*\]"?$/; 13 | 14 | ``` 15 | 16 | ### Unknown Global 17 | 18 | **Global**: `Ember.inject` 19 | 20 | **Location**: `tests/dummy/app/routes/application.js` at line 3 21 | 22 | ```js 23 | import Ember from 'ember'; 24 | 25 | const { inject } = Ember; 26 | 27 | export default Ember.Route.extend({ 28 | ``` 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ember-query-params 2 | 3 | Ember service for your query params 4 | 5 | :construction: Please use [ember-parachute] or [ember-query-params-service] instead. 6 | 7 | [![NPM][npm-badge-img]][npm-badge-link] 8 | [![Build Status][travis-badge]][travis-badge-url] 9 | [![Ember Observer Score][ember-observer-badge]][ember-observer-url] 10 | ![Ember Version][ember-version] 11 | 12 | This addon is in response to https://github.com/emberjs/ember.js/issues/11592. 13 | The idea came from [Robert Jackson]. 14 | 15 | See the [Changelog] for version changes. 16 | 17 | ## Compatibility 18 | 19 | * Ember.js v2.18 or above 20 | * Ember CLI v2.13 or above 21 | * Node.js v8 or above 22 | 23 | 24 | ## How It Works 25 | 26 | Basically the idea is that there is a central service that stores all QP values 27 | and from which you can subscribe to QP changes. 28 | 29 | We make this simple by providing a mixin for your route that sets up default QP 30 | values on the service from your controller, and hooks into the system for QP changes 31 | on URL updates. The controller also gets automatic subscriptions for all of it's own 32 | QPs. 33 | 34 | You can also use the service yourself, i.e. `paramsRelay: Ember.inject.service()` anywhere 35 | else, and get access to setting, getting and subscribing to the QP changes. 36 | 37 | 38 | ## Usage 39 | 40 | Setup your route with the `AutoSubscribe` mixin so we can listen for changes 41 | in query params from the URL, and also setup automatic subscribes for all 42 | of the query params on the related controller. 43 | 44 | ```js 45 | // my-route.js 46 | import Route from '@ember/routing/route'; 47 | import AutosubscribeMixin from 'ember-query-params/mixins/autosubscribe'; 48 | 49 | export default Route.extend(AutosubscribeMixin, { 50 | // If overriding `beforeModel`, make sure to call `this._super(...arguments)`. 51 | // Whatever else you have.. 52 | }); 53 | ``` 54 | 55 | The `AutoSubscribe` mixin requires that your controller has `queryParams` array 56 | setup to start relaying query params to the `paramsRelay` service. 57 | 58 | ```js 59 | // my-controller.js 60 | import Controller from '@ember/controller'; 61 | 62 | export default Controller.extend({ 63 | queryParams: [ 64 | 'theme', 65 | { isSidebarOpen: 'sidebar' } 66 | ], 67 | isSidebarOpen: false, 68 | theme: 'default' 69 | }); 70 | ``` 71 | 72 | 73 | ## Service API 74 | 75 | #### `setParam` 76 | 77 | Function signature `paramsRelay.setParam('name', value)`. 78 | 79 | #### `getParam` 80 | 81 | Function signature `paramsRelay.getParam('name')`. Returns the value, can be anything. 82 | 83 | #### `setParams` 84 | 85 | Function signature `paramsRelay.setParams(obj)`. 86 | A helper method to set many query params at once. Suggested usage includes 87 | using in the route, i.e. `paramsRelay.setParams(this.paramsFor(this.routeName))`. 88 | 89 | #### `hasParams` 90 | 91 | Function signature `paramsRelay.hasParams()`. 92 | Returns a boolean, letting you know if any params have been set on the service. 93 | 94 | #### `subscribe` 95 | 96 | Function signature `paramsRelay.subscribe('name', (key, value) => { //do something });`. 97 | 98 | #### `unsubscribe` 99 | 100 | Function signature `paramsRelay.unsubscribe('name', sameFunctionUsedInSubscribe)`. 101 | The function you passed to `subscribe` must be the same one passed to `unsubscribe` to remove it from 102 | the list of callbacks to notify on change. 103 | 104 | #### `autoSubscribe` 105 | 106 | Function signature `paramsRelay.autoSubscribe(this)`. 107 | Where `this` is the controller that has a `queryParams` array. 108 | All default query param values from the controller are set on the `paramsRelay` service. 109 | All query params must have a unique name, since setting a 'theme' in one controller will set the same QP in another. 110 | 111 | 112 | ## Custom Service 113 | 114 | You can also setup your own service, just use the mixin. 115 | 116 | ```js 117 | import Service from '@ember/service'; 118 | import QPMixin from 'ember-query-params/mixins/query-params'; 119 | 120 | export default Service.extend(QPMixin, { 121 | // your code 122 | }); 123 | ``` 124 | 125 | ## Contributing 126 | 127 | See [CONTRIBUTING.md]. 128 | 129 | [ember-parachute]: https://github.com/offirgolan/ember-parachute 130 | [ember-query-params-service]: https://github.com/NullVoxPopuli/ember-query-params-service 131 | [npm-badge-img]: https://badge.fury.io/js/ember-query-params.svg 132 | [npm-badge-link]: http://badge.fury.io/js/ember-query-params 133 | [travis-badge]: https://travis-ci.org/knownasilya/ember-query-params.svg 134 | [travis-badge-url]: https://travis-ci.org/knownasilya/ember-query-params 135 | [ember-observer-badge]: http://emberobserver.com/badges/ember-query-params.svg 136 | [ember-observer-url]: http://emberobserver.com/addons/ember-query-params 137 | [ember-version]: https://embadge.io/v1/badge.svg?start=1.13.0 138 | [Robert Jackson]: https://github.com/rwjblue 139 | [polyfill]: https://github.com/babel/ember-cli-babel#polyfill 140 | [CONTRIBUTING.md]: CONTRIBUTING.md 141 | [Changelog]: CHANGELOG.md 142 | -------------------------------------------------------------------------------- /addon/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knownasilya/ember-query-params/38fdcbc67ea6f3e9234800eb0968c0336bf9584a/addon/.gitkeep -------------------------------------------------------------------------------- /addon/mixins/autosubscribe.js: -------------------------------------------------------------------------------- 1 | import { inject as service } from '@ember/service'; 2 | import { schedule } from '@ember/runloop'; 3 | import Mixin from '@ember/object/mixin'; 4 | import { typeOf } from '@ember/utils'; 5 | const arrRegex = /^"?\[.*,*\]"?$/; 6 | 7 | export default Mixin.create({ 8 | paramsRelay: service(), 9 | 10 | beforeModel() { 11 | var paramsRelay = this.get('paramsRelay'); 12 | var routeName = this.routeName || this.router.currentRouteName; 13 | var controller = this.controllerFor(routeName); 14 | 15 | if (!this._eqpSubscribed) { 16 | paramsRelay.autoSubscribe(controller); 17 | this._eqpSubscribed = true; 18 | } 19 | 20 | // Set initial QPs since action fires first 21 | if (this._initialQps) { 22 | schedule('afterRender', this, () => { 23 | paramsRelay.setParams(this._initialQps); 24 | this._initialQps = undefined; 25 | }); 26 | } 27 | 28 | return this._super(...arguments); 29 | }, 30 | 31 | subscribeParam(name, cb) { 32 | var paramsRelay = this.get('paramsRelay'); 33 | 34 | paramsRelay.subscribe(name, cb); 35 | }, 36 | 37 | unsubscribeParam(name, cb) { 38 | var paramsRelay = this.get('paramsRelay'); 39 | 40 | paramsRelay.unsubscribe(name, cb); 41 | }, 42 | 43 | actions: { 44 | queryParamsDidChange(changed) { 45 | var paramsRelay = this.get('paramsRelay'); 46 | var routeName = this.routeName || this.router.currentRouteName; 47 | var params = this.paramsFor(routeName); 48 | var changedKeys = Object.keys(changed); 49 | var deserialized = changedKeys.reduce((res, key) => { 50 | let raw = params[key]; 51 | let changedRaw = changed[key]; 52 | let normalized = normalizeArrayQp(changedRaw); 53 | let value = this.deserializeQueryParam(normalized, key, normalized && normalized.match(arrRegex) ? 'array' : typeOf(raw)); 54 | 55 | res[key] = value; 56 | return res; 57 | }, {}); 58 | 59 | if (changedKeys.length && this._eqpSubscribed) { 60 | paramsRelay.setParams(deserialized); 61 | } else if (!paramsRelay.hasParams() && changedKeys.length && !this._eqpSubscribed) { 62 | this._initialQps = deserialized; 63 | } 64 | 65 | return this._super(...arguments); 66 | } 67 | } 68 | }); 69 | 70 | function normalizeArrayQp(val) { 71 | var matched = val && val.match(/^"(\[.*,*\])"$/); 72 | if (matched) { 73 | try { 74 | return JSON.parse(matched[1]); 75 | } catch(e) { 76 | // noop 77 | } 78 | } 79 | 80 | return val; 81 | } 82 | -------------------------------------------------------------------------------- /addon/mixins/query-params.js: -------------------------------------------------------------------------------- 1 | import { run } from '@ember/runloop'; 2 | import Mixin from '@ember/object/mixin'; 3 | import { get } from '@ember/object'; 4 | import { typeOf } from '@ember/utils'; 5 | 6 | export default Mixin.create({ 7 | init() { 8 | this._super(...arguments); 9 | this._map = {}; 10 | }, 11 | 12 | setParam(name, value) { 13 | let map = this._map; 14 | let item = map[name]; 15 | let oldValue; 16 | let sameValues; 17 | 18 | if (item) { 19 | oldValue = item.value; 20 | 21 | if (typeOf(value) === 'array') { 22 | item.value = value.copy(); 23 | try { 24 | sameValues = JSON.stringify(value) === JSON.stringify(oldValue); 25 | } catch(e) { 26 | // noop 27 | } 28 | } else { 29 | item.value = value; 30 | sameValues = oldValue === value; 31 | } 32 | 33 | if (!sameValues) { 34 | this.callCbs(name); 35 | } 36 | } else { 37 | map[name] = { 38 | value, 39 | cbs: [] 40 | }; 41 | } 42 | }, 43 | 44 | getParam(name) { 45 | let map = this._map; 46 | let item = map[name]; 47 | 48 | return item ? item.value : undefined; 49 | }, 50 | 51 | setParams(hash) { 52 | if (!hash) { 53 | return; 54 | } 55 | 56 | Object.keys(hash).forEach(key => { 57 | let value = hash[key]; 58 | this.setParam(key, value); 59 | }); 60 | }, 61 | 62 | hasParams() { 63 | return Object.keys(this._map).length > 0; 64 | }, 65 | 66 | subscribe(name, cb) { 67 | let map = this._map; 68 | let item = map[name]; 69 | 70 | if (item) { 71 | item.cbs.push(cb); 72 | } else { 73 | map[name] = { 74 | value: undefined, 75 | cbs: [cb] 76 | }; 77 | } 78 | }, 79 | 80 | unsubscribe(name, cb) { 81 | let map = this._map; 82 | let item = map[name]; 83 | 84 | if (item) { 85 | let index = item.cbs.indexOf(cb); 86 | 87 | if (index !== -1) { 88 | item.cbs.splice(index, 1); 89 | } 90 | } 91 | }, 92 | 93 | autoSubscribe(context) { 94 | if (!context || !context.queryParams) { 95 | return; 96 | } 97 | 98 | let keys = context.queryParams.reduce((all, item) => { 99 | if (typeof item === 'string') { 100 | all.push(item); 101 | } else if (typeof item === 'object') { 102 | all = all.concat(Object.keys(item)); 103 | } 104 | 105 | return all; 106 | }, []); 107 | let update = (name, val) => { 108 | if (context.isDestroyed || context.isDestroying) { 109 | return; 110 | } 111 | 112 | run(context, 'set', name, val); 113 | }; 114 | 115 | keys.forEach(key => { 116 | // only set if it doesn't exist yet 117 | if (!this._map[key]) { 118 | this.setParam(key, get(context, key)); 119 | } 120 | this.subscribe(key, update); 121 | }); 122 | 123 | let originalWillDestroy = context.willDestroy; 124 | // Override willDestroy to cleanup handlers 125 | if (originalWillDestroy) { 126 | context.willDestroy = () => { 127 | keys.forEach(key => this.unsubscribe(key, update)); 128 | originalWillDestroy(...arguments); 129 | }; 130 | } 131 | }, 132 | 133 | callCbs(name) { 134 | let map = this._map; 135 | let item = map[name]; 136 | 137 | if (item) { 138 | item.cbs.forEach(cb => cb(name, item.value)); 139 | } 140 | } 141 | }); 142 | -------------------------------------------------------------------------------- /addon/services/params-relay.js: -------------------------------------------------------------------------------- 1 | import Service from '@ember/service'; 2 | import QPMixin from '../mixins/query-params'; 3 | 4 | export default Service.extend(QPMixin, {}); 5 | -------------------------------------------------------------------------------- /app/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knownasilya/ember-query-params/38fdcbc67ea6f3e9234800eb0968c0336bf9584a/app/.gitkeep -------------------------------------------------------------------------------- /app/services/params-relay.js: -------------------------------------------------------------------------------- 1 | export { default } from 'ember-query-params/services/params-relay'; 2 | -------------------------------------------------------------------------------- /config/ember-try.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const getChannelURL = require('ember-source-channel-url'); 4 | 5 | module.exports = function() { 6 | return Promise.all([ 7 | getChannelURL('release'), 8 | getChannelURL('beta'), 9 | getChannelURL('canary') 10 | ]).then((urls) => { 11 | return { 12 | scenarios: [ 13 | { 14 | name: 'ember-lts-2.18', 15 | env: { 16 | EMBER_OPTIONAL_FEATURES: JSON.stringify({ 'jquery-integration': true }) 17 | }, 18 | npm: { 19 | devDependencies: { 20 | '@ember/jquery': '^0.5.1', 21 | 'ember-source': '~2.18.0' 22 | } 23 | } 24 | }, 25 | { 26 | name: 'ember-lts-3.4', 27 | npm: { 28 | devDependencies: { 29 | 'ember-source': '~3.4.0' 30 | } 31 | } 32 | }, 33 | { 34 | name: 'ember-release', 35 | npm: { 36 | devDependencies: { 37 | 'ember-source': urls[0] 38 | } 39 | } 40 | }, 41 | { 42 | name: 'ember-beta', 43 | npm: { 44 | devDependencies: { 45 | 'ember-source': urls[1] 46 | } 47 | } 48 | }, 49 | { 50 | name: 'ember-canary', 51 | npm: { 52 | devDependencies: { 53 | 'ember-source': urls[2] 54 | } 55 | } 56 | }, 57 | // The default `.travis.yml` runs this scenario via `npm test`, 58 | // not via `ember try`. It's still included here so that running 59 | // `ember try:each` manually or from a customized CI config will run it 60 | // along with all the other scenarios. 61 | { 62 | name: 'ember-default', 63 | npm: { 64 | devDependencies: {} 65 | } 66 | }, 67 | { 68 | name: 'ember-default-with-jquery', 69 | env: { 70 | EMBER_OPTIONAL_FEATURES: JSON.stringify({ 71 | 'jquery-integration': true 72 | }) 73 | }, 74 | npm: { 75 | devDependencies: { 76 | '@ember/jquery': '^0.5.1' 77 | } 78 | } 79 | } 80 | ] 81 | }; 82 | }); 83 | }; 84 | -------------------------------------------------------------------------------- /config/environment.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(/* environment, appConfig */) { 4 | return { }; 5 | }; 6 | -------------------------------------------------------------------------------- /ember-cli-build.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const EmberAddon = require('ember-cli/lib/broccoli/ember-addon'); 4 | 5 | module.exports = function(defaults) { 6 | let app = new EmberAddon(defaults, { 7 | // Add options here 8 | }); 9 | 10 | /* 11 | This build file specifies the options for the dummy test app of this 12 | addon, located in `/tests/dummy` 13 | This build file does *not* influence how the addon or the app using it 14 | behave. You most likely want to be modifying `./index.js` or app's build file 15 | */ 16 | 17 | return app.toTree(); 18 | }; 19 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | name: require('./package').name 5 | }; 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ember-query-params", 3 | "version": "2.1.2", 4 | "description": "Ember service for your query params", 5 | "keywords": [ 6 | "ember-addon", 7 | "query params", 8 | "qps", 9 | "service", 10 | "subscribe", 11 | "url" 12 | ], 13 | "repository": "https://github.com/knownasilya/ember-query-params", 14 | "license": "MIT", 15 | "author": "Ilya Radchenko ", 16 | "directories": { 17 | "doc": "doc", 18 | "test": "tests" 19 | }, 20 | "scripts": { 21 | "build": "ember build", 22 | "lint:hbs": "ember-template-lint .", 23 | "lint:js": "eslint .", 24 | "start": "ember serve", 25 | "test": "ember test", 26 | "test:all": "ember try:each", 27 | "test-default": "ember try:one default --- ember test", 28 | "release": "standard-version" 29 | }, 30 | "dependencies": { 31 | "ember-cli-babel": "^7.7.3" 32 | }, 33 | "devDependencies": { 34 | "@ember/optional-features": "^0.7.0", 35 | "broccoli-asset-rev": "^3.0.0", 36 | "ember-cli": "~3.10.1", 37 | "ember-cli-dependency-checker": "^3.1.0", 38 | "ember-cli-eslint": "^5.1.0", 39 | "ember-cli-github-pages": "^0.2.1", 40 | "ember-cli-htmlbars": "^3.0.1", 41 | "ember-cli-htmlbars-inline-precompile": "^2.1.0", 42 | "ember-cli-inject-live-reload": "^1.8.2", 43 | "ember-cli-sri": "^2.1.1", 44 | "ember-cli-template-lint": "^1.0.0-beta.1", 45 | "ember-cli-uglify": "^2.1.0", 46 | "ember-disable-prototype-extensions": "^1.1.3", 47 | "ember-export-application-global": "^2.0.0", 48 | "ember-load-initializers": "^2.0.0", 49 | "ember-maybe-import-regenerator": "^0.1.6", 50 | "ember-qunit": "^4.4.1", 51 | "ember-resolver": "^5.0.1", 52 | "ember-source": "~3.10.0", 53 | "ember-source-channel-url": "^1.1.0", 54 | "ember-try": "^1.0.0", 55 | "eslint-plugin-ember": "^6.2.0", 56 | "eslint-plugin-node": "^9.0.1", 57 | "loader.js": "^4.7.0", 58 | "qunit-dom": "^0.8.4", 59 | "standard-version": "^8.0.1" 60 | }, 61 | "engines": { 62 | "node": "8.* || >= 10.*" 63 | }, 64 | "ember-addon": { 65 | "configPath": "tests/dummy/config", 66 | "demoURL": "http://knownasilya.github.io/ember-query-params/" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /testem.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | test_page: 'tests/index.html?hidepassed', 3 | disable_watching: true, 4 | launch_in_ci: [ 5 | 'Chrome' 6 | ], 7 | launch_in_dev: [ 8 | 'Chrome' 9 | ], 10 | browser_args: { 11 | Chrome: { 12 | ci: [ 13 | // --no-sandbox is needed when running Chrome inside a container 14 | process.env.CI ? '--no-sandbox' : null, 15 | '--headless', 16 | '--disable-gpu', 17 | '--disable-dev-shm-usage', 18 | '--disable-software-rasterizer', 19 | '--mute-audio', 20 | '--remote-debugging-port=0', 21 | '--window-size=1440,900' 22 | ].filter(Boolean) 23 | } 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /tests/dummy/app/app.js: -------------------------------------------------------------------------------- 1 | import Application from '@ember/application'; 2 | import Resolver from './resolver'; 3 | import loadInitializers from 'ember-load-initializers'; 4 | import config from './config/environment'; 5 | 6 | const App = Application.extend({ 7 | modulePrefix: config.modulePrefix, 8 | podModulePrefix: config.podModulePrefix, 9 | Resolver 10 | }); 11 | 12 | loadInitializers(App, config.modulePrefix); 13 | 14 | export default App; 15 | -------------------------------------------------------------------------------- /tests/dummy/app/components/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knownasilya/ember-query-params/38fdcbc67ea6f3e9234800eb0968c0336bf9584a/tests/dummy/app/components/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/controllers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knownasilya/ember-query-params/38fdcbc67ea6f3e9234800eb0968c0336bf9584a/tests/dummy/app/controllers/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/controllers/application.js: -------------------------------------------------------------------------------- 1 | import { inject as service } from '@ember/service'; 2 | import Controller from '@ember/controller'; 3 | 4 | export default Controller.extend({ 5 | paramsRelay: service('params-relay'), 6 | appName: 'Ember Twiddle', 7 | queryParams: ['theme', { isSidebar: 'sidebar' }], 8 | theme: 'bye', 9 | isSidebar: false, 10 | counter: 0, 11 | 12 | init() { 13 | this._super(...arguments); 14 | var paramsRelay = this.get('paramsRelay'); 15 | 16 | paramsRelay.autoSubscribe(this); 17 | paramsRelay.subscribe('theme', (key, theme) => this.set('theme2', theme+2)); 18 | //paramsRelay.subscribe('theme', (key, theme) => this.set('theme', theme)); 19 | }, 20 | 21 | actions: { 22 | updateTheme() { 23 | var paramsRelay = this.get('paramsRelay'); 24 | var counter = this.incrementProperty('counter'); 25 | 26 | paramsRelay.setParam('theme', `hi${counter}`); 27 | paramsRelay.setParam('isSidebar', counter % 2 === 1); 28 | } 29 | } 30 | }); 31 | -------------------------------------------------------------------------------- /tests/dummy/app/controllers/test.js: -------------------------------------------------------------------------------- 1 | import Controller from '@ember/controller'; 2 | 3 | export default Controller.extend({ 4 | queryParams: [ 5 | 'hello', 6 | { myName: 'name' } 7 | ] 8 | }); 9 | -------------------------------------------------------------------------------- /tests/dummy/app/helpers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knownasilya/ember-query-params/38fdcbc67ea6f3e9234800eb0968c0336bf9584a/tests/dummy/app/helpers/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ember-query-params 7 | 8 | 9 | 10 | {{content-for "head"}} 11 | 12 | 13 | 14 | 15 | {{content-for "head-footer"}} 16 | 17 | 18 | {{content-for "body"}} 19 | 20 | 21 | 22 | 23 | {{content-for "body-footer"}} 24 | 25 | 26 | -------------------------------------------------------------------------------- /tests/dummy/app/models/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knownasilya/ember-query-params/38fdcbc67ea6f3e9234800eb0968c0336bf9584a/tests/dummy/app/models/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/resolver.js: -------------------------------------------------------------------------------- 1 | import Resolver from 'ember-resolver'; 2 | 3 | export default Resolver; 4 | -------------------------------------------------------------------------------- /tests/dummy/app/router.js: -------------------------------------------------------------------------------- 1 | import EmberRouter from '@ember/routing/router'; 2 | import config from './config/environment'; 3 | 4 | const Router = EmberRouter.extend({ 5 | location: config.locationType, 6 | rootURL: config.rootURL 7 | }); 8 | 9 | Router.map(function() { 10 | this.route('test'); 11 | }); 12 | 13 | export default Router; 14 | -------------------------------------------------------------------------------- /tests/dummy/app/routes/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knownasilya/ember-query-params/38fdcbc67ea6f3e9234800eb0968c0336bf9584a/tests/dummy/app/routes/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/routes/application.js: -------------------------------------------------------------------------------- 1 | import { inject as service } from '@ember/service'; 2 | import Route from '@ember/routing/route'; 3 | 4 | export default Route.extend({ 5 | paramsRelay: service(), 6 | 7 | actions: { 8 | queryParamsDidChange() { 9 | var paramsRelay = this.get('paramsRelay'); 10 | 11 | paramsRelay.setParams(this.paramsFor(this.routeName)); 12 | } 13 | } 14 | }); 15 | -------------------------------------------------------------------------------- /tests/dummy/app/routes/test.js: -------------------------------------------------------------------------------- 1 | import Route from '@ember/routing/route'; 2 | import AutoSubscribeMixin from 'ember-query-params/mixins/autosubscribe'; 3 | 4 | export default Route.extend(AutoSubscribeMixin, { 5 | }); 6 | -------------------------------------------------------------------------------- /tests/dummy/app/styles/app.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knownasilya/ember-query-params/38fdcbc67ea6f3e9234800eb0968c0336bf9584a/tests/dummy/app/styles/app.css -------------------------------------------------------------------------------- /tests/dummy/app/templates/application.hbs: -------------------------------------------------------------------------------- 1 |

ember-query-params

2 |
3 |
4 | {{outlet}} 5 |
6 |
7 | 8 |
9 | {{this.theme}}
10 | {{this.theme2}}
11 | {{this.isSidebar}} 12 | 13 | {{#link-to "test"}}Test{{/link-to}} 14 | -------------------------------------------------------------------------------- /tests/dummy/app/templates/components/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knownasilya/ember-query-params/38fdcbc67ea6f3e9234800eb0968c0336bf9584a/tests/dummy/app/templates/components/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/templates/test.hbs: -------------------------------------------------------------------------------- 1 |

Test

2 | 3 | {{#link-to "index"}}Home{{/link-to}} 4 | 5 |
6 | {{this.hello}}
7 | {{this.myName}} 8 | -------------------------------------------------------------------------------- /tests/dummy/config/environment.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(environment) { 4 | let ENV = { 5 | modulePrefix: 'dummy', 6 | environment, 7 | rootURL: '/', 8 | locationType: 'auto', 9 | EmberENV: { 10 | FEATURES: { 11 | // Here you can enable experimental features on an ember canary build 12 | // e.g. EMBER_NATIVE_DECORATOR_SUPPORT: true 13 | }, 14 | EXTEND_PROTOTYPES: { 15 | // Prevent Ember Data from overriding Date.parse. 16 | Date: false 17 | } 18 | }, 19 | 20 | APP: { 21 | // Here you can pass flags/options to your application instance 22 | // when it is created 23 | } 24 | }; 25 | 26 | if (environment === 'development') { 27 | // ENV.APP.LOG_RESOLVER = true; 28 | // ENV.APP.LOG_ACTIVE_GENERATION = true; 29 | // ENV.APP.LOG_TRANSITIONS = true; 30 | // ENV.APP.LOG_TRANSITIONS_INTERNAL = true; 31 | // ENV.APP.LOG_VIEW_LOOKUPS = true; 32 | } 33 | 34 | if (environment === 'test') { 35 | // Testem prefers this... 36 | ENV.locationType = 'none'; 37 | 38 | // keep test console output quieter 39 | ENV.APP.LOG_ACTIVE_GENERATION = false; 40 | ENV.APP.LOG_VIEW_LOOKUPS = false; 41 | 42 | ENV.APP.rootElement = '#ember-testing'; 43 | ENV.APP.autoboot = false; 44 | } 45 | 46 | if (environment === 'production') { 47 | ENV.locationType = 'hash'; 48 | ENV.baseURL = '/ember-query-params/'; 49 | } 50 | 51 | return ENV; 52 | }; 53 | -------------------------------------------------------------------------------- /tests/dummy/config/optional-features.json: -------------------------------------------------------------------------------- 1 | { 2 | "jquery-integration": false 3 | } 4 | -------------------------------------------------------------------------------- /tests/dummy/config/targets.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const browsers = [ 4 | 'last 1 Chrome versions', 5 | 'last 1 Firefox versions', 6 | 'last 1 Safari versions' 7 | ]; 8 | 9 | const isCI = !!process.env.CI; 10 | const isProduction = process.env.EMBER_ENV === 'production'; 11 | 12 | if (isCI || isProduction) { 13 | browsers.push('ie 11'); 14 | } 15 | 16 | module.exports = { 17 | browsers 18 | }; 19 | -------------------------------------------------------------------------------- /tests/dummy/public/robots.txt: -------------------------------------------------------------------------------- 1 | # http://www.robotstxt.org 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /tests/helpers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knownasilya/ember-query-params/38fdcbc67ea6f3e9234800eb0968c0336bf9584a/tests/helpers/.gitkeep -------------------------------------------------------------------------------- /tests/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Dummy Tests 7 | 8 | 9 | 10 | {{content-for "head"}} 11 | {{content-for "test-head"}} 12 | 13 | 14 | 15 | 16 | 17 | {{content-for "head-footer"}} 18 | {{content-for "test-head-footer"}} 19 | 20 | 21 | {{content-for "body"}} 22 | {{content-for "test-body"}} 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | {{content-for "body-footer"}} 31 | {{content-for "test-body-footer"}} 32 | 33 | 34 | -------------------------------------------------------------------------------- /tests/integration/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knownasilya/ember-query-params/38fdcbc67ea6f3e9234800eb0968c0336bf9584a/tests/integration/.gitkeep -------------------------------------------------------------------------------- /tests/test-helper.js: -------------------------------------------------------------------------------- 1 | import Application from '../app'; 2 | import config from '../config/environment'; 3 | import { setApplication } from '@ember/test-helpers'; 4 | import { start } from 'ember-qunit'; 5 | 6 | setApplication(Application.create(config.APP)); 7 | 8 | start(); 9 | -------------------------------------------------------------------------------- /tests/unit/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knownasilya/ember-query-params/38fdcbc67ea6f3e9234800eb0968c0336bf9584a/tests/unit/.gitkeep -------------------------------------------------------------------------------- /tests/unit/mixins/autosubscribe-test.js: -------------------------------------------------------------------------------- 1 | import { run } from '@ember/runloop'; 2 | import EmberObject from '@ember/object'; 3 | import { module, test } from 'qunit'; 4 | import { setupTest } from 'ember-qunit'; 5 | 6 | module('route:test', function(hooks) { 7 | setupTest(hooks); 8 | 9 | test('it works', function(assert) { 10 | let controllerStub = EmberObject.create({ 11 | queryParams: [ 12 | 'hello', 13 | { myName: 'name' } 14 | ] 15 | }); 16 | let subject = this.owner.lookup('route:test'); 17 | let relay = subject.get('paramsRelay'); 18 | 19 | subject.routeName = 'test'; 20 | subject.controller = controllerStub; 21 | subject.controllerFor = function () { 22 | return subject.controller; 23 | }; 24 | 25 | subject.beforeModel(); 26 | 27 | relay.setParam('hello', 'bob'); 28 | relay.setParam('myName', 'john'); 29 | 30 | assert.equal(subject.controller.get('hello'), 'bob'); 31 | assert.equal(subject.controller.get('myName'), 'john'); 32 | }); 33 | 34 | test('auto unsubscribe', function(assert) { 35 | let controllerStub = EmberObject.create({ 36 | queryParams: [ 37 | 'hello', 38 | { myName: 'name' } 39 | ] 40 | }); 41 | let subject = this.owner.lookup('route:test'); 42 | let relay = subject.get('paramsRelay'); 43 | let originalDestroy = subject.destroy; 44 | let local; 45 | 46 | subject.routeName = 'test'; 47 | subject.controller = controllerStub; 48 | subject.controllerFor = function () { 49 | return subject.controller; 50 | }; 51 | subject.destroy = function () { 52 | subject.controller.destroy(); 53 | originalDestroy.call(subject, ...arguments); 54 | }; 55 | 56 | subject.beforeModel(); 57 | 58 | relay.subscribe('hello', (key, val) => { 59 | local = val; 60 | }); 61 | 62 | relay.setParam('hello', 'bob'); 63 | relay.setParam('myName', 'john'); 64 | 65 | assert.equal(subject.controller.get('hello'), 'bob'); 66 | assert.equal(subject.controller.get('myName'), 'john'); 67 | assert.equal(local, 'bob'); 68 | 69 | run(() => { 70 | subject.destroy(); 71 | }); 72 | 73 | relay.setParam('hello', 'bob2'); 74 | relay.setParam('myName', 'john2'); 75 | 76 | assert.equal(subject.controller.get('hello'), 'bob'); 77 | assert.equal(subject.controller.get('myName'), 'john'); 78 | // other functions still present 79 | assert.equal(local, 'bob2'); 80 | }); 81 | }); 82 | -------------------------------------------------------------------------------- /tests/unit/mixins/query-params-test.js: -------------------------------------------------------------------------------- 1 | import EmberObject from '@ember/object'; 2 | import QueryParamsMixin from 'ember-query-params/mixins/query-params'; 3 | import { module, test } from 'qunit'; 4 | 5 | module('Unit | Mixin | query params', function() { 6 | // Replace this with your real tests. 7 | test('it works', function(assert) { 8 | let QueryParamsObject = EmberObject.extend(QueryParamsMixin); 9 | let subject = QueryParamsObject.create(); 10 | assert.ok(subject); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /tests/unit/services/params-relay-test.js: -------------------------------------------------------------------------------- 1 | import EmberObject from '@ember/object'; 2 | import { module, test } from 'qunit'; 3 | import { setupTest } from 'ember-qunit'; 4 | 5 | module('Unit | Service | params relay', function(hooks) { 6 | setupTest(hooks); 7 | 8 | test('setting a param', function(assert) { 9 | let service = this.owner.lookup('service:params-relay'); 10 | 11 | assert.notOk(service.getParam('name')); 12 | service.setParam('name', 'bob'); 13 | 14 | assert.equal(service.getParam('name'), 'bob'); 15 | service.setParam('name', 'john'); 16 | 17 | assert.equal(service.getParam('name'), 'john'); 18 | }); 19 | 20 | test('subscribe fired on set', function(assert) { 21 | let service = this.owner.lookup('service:params-relay'); 22 | 23 | service.subscribe('test', (key, val) => { 24 | assert.equal(key, 'test'); 25 | assert.equal(val, 'blah'); 26 | }); 27 | 28 | assert.notOk(service.getParam('test')); 29 | service.setParam('test', 'blah'); 30 | }); 31 | 32 | test('autoSubscribe changes values', function(assert) { 33 | let service = this.owner.lookup('service:params-relay'); 34 | let target = EmberObject.create({ 35 | queryParams: [ 36 | 'hello', 37 | { myName: 'name' } 38 | ], 39 | hello: 'hi', 40 | myName: 'betty' 41 | }); 42 | 43 | service.autoSubscribe(target); 44 | 45 | // set default values 46 | assert.equal(service.getParam('hello'), 'hi'); 47 | assert.equal(service.getParam('myName'), 'betty'); 48 | 49 | service.setParam('hello', 'bob'); 50 | service.setParam('myName', 'john'); 51 | 52 | assert.equal(target.get('hello'), 'bob'); 53 | assert.equal(target.get('myName'), 'john'); 54 | }); 55 | 56 | test('unsubscribe', function(assert) { 57 | let service = this.owner.lookup('service:params-relay'); 58 | let counter1 = 0; 59 | let counter2 = 0; 60 | let onTest = (key, val) => { 61 | assert.equal(key, 'test'); 62 | assert.equal(val, 'blah'); 63 | counter1++; 64 | }; 65 | let onTest2 = (key, val) => { 66 | assert.equal(key, 'test'); 67 | assert.equal(val, counter2 === 0 ? 'blah' : 'blah2'); 68 | counter2++; 69 | }; 70 | 71 | service.subscribe('test', onTest); 72 | service.subscribe('test', onTest2); 73 | 74 | assert.notOk(service.getParam('test')); 75 | service.setParam('test', 'blah'); 76 | 77 | service.unsubscribe('test', onTest); 78 | 79 | assert.equal(service.getParam('test'), 'blah'); 80 | service.setParam('test', 'blah2'); 81 | assert.equal(service.getParam('test'), 'blah2'); 82 | assert.equal(counter2, 2); 83 | assert.equal(counter1, 1); 84 | }); 85 | }); 86 | -------------------------------------------------------------------------------- /vendor/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knownasilya/ember-query-params/38fdcbc67ea6f3e9234800eb0968c0336bf9584a/vendor/.gitkeep --------------------------------------------------------------------------------