Git Product home page Git Product logo

ember-jsonapi-resources's People

Contributors

aars avatar andrewmp1 avatar barelyknown avatar cibernox avatar ember-tomster avatar erikap avatar pixelhandler avatar proteamer avatar realityendshere avatar vovanbo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ember-jsonapi-resources's Issues

Resource generator, routing structure + integration with JSONAPI::Resources

(Question about usage really, wasn't sure whether to post this on StackOverflow. I didn't find any ember-jsonapi-resources questions or tags there, so asking here. Happy to update the README accordingly afterwards, if relevant for documentation)

I have a rails api using JR, with a /proposals endpoint for a Proposal resource/model. I'm building a form for a new proposal on my ember front-end, and after installing ember-jsonapi-resources I generated a resource with ember g resource proposal.

I noticed the route generated and appended to router.js is in the singular, which threw me off a bit - I was (naively, probably) expecting a route in the plural, matching the rails convention, and since the jsonapi convention is also to refer to resources in the plural.

What's the recommended way to structure routes, that will work most seamlessly with ember-jsonapi-resources/JR? The dummy app's routing structure seems a little fuzzy on this:

  this.route('index', { path: '/' });
  this.resource('post', { path: '/:post_id' }, function () {
    this.route('detail', { path: '/' });
    this.route('comments');
  });
  this.route('admin', function () {
    this.route('index');
    this.route('create');
    this.route('edit', { path: ':edit_id' });
  });

For the proposal resource creation example, should a route for new (or create?) be nested under the singular proposal route like this?

this.route('proposal', function() {
  this.route('new');
  // # and then,
  //this.route('edit'); ?
  // # and possibly
  //this.route('index'); ?
});

...Or does it simply not matter, and any route structure will work the same with both ember-jsonapi-resources and JR?

Update docs for [create|patch|delete]Relationship service methods

Need to revisit the does on this code - https://github.com/pixelhandler/ember-jsonapi-resources/blob/master/addon/adapters/application.js#L192-L252

  • According to JSON API Spec to-one relationship should only use PATCH, use patchRelationship only for to-one
  • And, to-many may use POST, PATCH, and DELETE
    • createRelationship is the POST method for to-many (and should not be used for to-one)

Also, add a wiki page to show how to manage relationships.

Why the separate call to hasRelated?

I just read through [resource.js](which was a real pleasure - such nice code). It wasn't clear to me why there needs to be a separate call to hasRelated to register the relationships (instead of having hasOne and hasMany do that). I suspect I'm missing a consideration in your design. Would you mind explaining?

Full tests

I think we need better tests. Some that test the entire chain of adapters, mixins, models, etc. The current unit tests are very fragile and rarely test actual use-cases (with server responses mocked, etc).

What do you guys think? I'm having a bit of trouble wrapping my mind around how that test-setup should look. Maybe blog-admin will suffice, but I believe that needs an actual (mock) backend, since the current proxy setup does not allow saving resources.

Any thoughts on how to set this up? Where to begin?

Create blueprints for Route files

Consider using the plural name for the resource or whether to follow the singular name like Ember uses in the default model hooks.

Broken build with older version of fetch & es6-promise packages

Build error:

The Broccoli Plugin: [SourceMapConcat: Concat: Vendor /assets/vendor.js] failed with:
Error: ENOENT: no such file or directory, stat '/usr/local/var/www/pipeline-briefs/tmp/source_map_concat-input_base_path-JeLUswcx.tmp/0/bower_components/es6-promise/es6-promise.js'

The solution is to upgrade…

⚡ ember install ember-jsonapi-resources
Installed packages for tooling via npm.
installing ember-jsonapi-resources
  install bower packages fetch, es6-promise
  install packages inflection, lodash, ember-inflector, ember-cli-string-utils, ember-cli-path-utils, ember-cli-test-info, ember-cli-get-dependency-depth, silent-error
  cached https://github.com/components/es6-promise.git#4.0.5
  cached https://github.com/github/fetch.git#1.0.0
  conflict Unable to find suitable version for es6-promise
    1) es6-promise ~3.0.2
    2) es6-promise ^4.0.5
? Answer 2
  conflict Unable to find suitable version for fetch
    1) fetch ~0.10.1
    2) fetch ^1.0.0
? Answer 2
Installed packages for tooling via npm.
Installed browser packages via Bower.
Installed addon package.

"Dasherize" resource attributes

Just recommending that keys given to Resource#attr be dasherized by default. This makes serialization same with the jsonapi-resources gem, and since the official spec hints at this convention anyway. Thanks!

New instances of resource retaining values from previous instances.

I cannot figure out why new instances of this resource are picking up an attribute from the previous resource. Any ideas?

var Game = ScoreboardWww.__container__.lookup('model:games');
var g1 = Game.create({isNew: true});

g1.get('name')
// ""

g1.set('name', 'asdf')
g1.get('name')
// "asdf"

g2 = Game.create({isNew: true});
g2.get('name');
// "asdf"
// WHY IS THIS NOT BLANK??????

g3 = Game.create({isNew: true, name: ''});
g3.get('name');
// ""

Proposal: Change key 'resource' to 'relation' in hasOne/hasMany object param.

If it's still the case that the optional {resource: 'direct-reports', type: 'employees'} isn't documented (much/well) I want to suggest to rename the resource property of that object to relation. So:

Resource.extend({
  directReports: hasMany({relation: 'direct-reports', type: 'employees'}), // suggested
  // directReports: hasMany({resource: 'direct-reports', type: 'employees'}) // current
});

2 reasons:

  1. Calling it resource is confusing since we're defining Resources all over the place, but that is not what it means in this case.
  2. The related-proxy stores this value as relation. Which is what we end up using internally. meta.relation.

Many times there isn't really a resource (either defined in terms of ember-jsonapi-resources or defined in terms of a JSONAPI url/resource to request) by this name. It is the name of the relationship a Resource has with some other Resource of a certain type. As defined by type.
To illustrate using urls:
http://api.pixelhandler.com/api/v1/supervisors/1/relationships/`resource`
vs
http://api.pixelhandler.com/api/v1/supervisors/1/relationships/`relation`
would make more sense since:
http://api.pixelhandler.com/api/v1/direct-reports does not exist. It is not a resource.

(I'll be happy to do the work for this. Including changes to docs)

Attribute values cannot be set on the creation of a resource.

The attributes object is not set up until init() is called, but that happens after create(). So, there's an error if you try to set an attribute during create.

import Resource from 'ember-jsonapi-resources/models/resource';
const Game = Resource.extend({
  type: 'games',
  name: attr()
});
Game.create({name: 'Foo'});
// Error: Property set failed: object in path "attributes" could not be found or was destroyed.

I'm not sure what the idiomatic way is to fix this, but the following works.

Resource.reopenClass({
  create(...args) {
    let i = this._super();
    i.setProperties(...args);
    return i;
  }
});

Firefox Fetch implementation is not working, JSON.parse errors

To reproduce, simply clone and setup this test repo and try to load in Firefox: https://github.com/pixelhandler/jr-test

With logging enabled you get this in the console:

Attempting URL transition to / vendor.js:59372:7
generated -> route:application Object { fullName: "route:application" } vendor.js:36898:1
Preparing to transition from '' to ' index' vendor.js:36658:9
Transition #0: application: calling beforeModel hook vendor.js:59369:7
Transition #0: application: calling deserialize hook vendor.js:59369:7
Transition #0: application: calling afterModel hook vendor.js:59369:7
Transition #0: index: calling beforeModel hook vendor.js:59369:7
Transition #0: index: calling deserialize hook vendor.js:59369:7
Error while processing route: index JSON.parse: unexpected character at line 1 column 1 of the JSON data vendor.js:37221:5
Transition #0: index: transition was aborted

@pixelhandler said:

I tried to debug but seems like the issue is somewhere in the polyfill the workaround is to use XHR instead of fetch which requires an alternative implementation of the adapter.fetch method which will take some time for me to get too.

model generator/blueprint broken?

using ember-cli 2.5.1 ember generate jsonapi-resource model-name [--classic] creates broken model files, it seems to have something to do with the length of model-name.

steps to reproduce:

$ ember new ember-jsonapi-resources-blueprint-test
$ cd ember-jsonapi-resources-blueprint-test
$ ember install ember-jsonapi-resources
$ ember generate jsonapi-resource resource-test --classic
$ ember generate jsonapi-resource testing
$ ember generate jsonapi-resource testing2

app/models/resource-test.js now looks like this:

export { default } from 'ember-jsonapi-resources-blueprint-test/models/resource-test';
e';
import { attr, hasOne, hasMany } from 'ember-jsonapi-resources/models/resource';

let ResourceTest = Resource.extend({
  type: 'resource-tests',
  service: Ember.inject.service('resource-tests'),


});

ResourceTest.reopenClass({

  getDefaults() {
    return {
      isNew: true,
      attributes: {}
    };
  }
});

export default ResourceTest;

The import/exports are broken. Not sure if the export { default } line should even be there.
app/model/testing.js

export { default } from 'ember-jsonapi-resources-blueprint-test/models/testing';
esource';
import { attr, hasOne, hasMany } from 'ember-jsonapi-resources/models/resource';

...

app/model/testing2.js:

xport { default } from 'ember-jsonapi-resources-blueprint-test/models/testing2';
source';
import { attr, hasOne, hasMany } from 'ember-jsonapi-resources/models/resource';

...

As you can see, the second line (which should import Resource) is 1 char shorter in testing2, which is why I think the model-name length is involved here.

Ember Inspector `Data` tab is throwing an error

Hi there!

I have been running the dummy app included in the repo and whenever I press on the Data tab of Ember Inspector I get this error:

  • Firefox
"Ember Inspector has errored.
This is likely a bug in the inspector itself.
You can report bugs at https://github.com/emberjs/ember-inspector.
Error message: adapter is undefined
Stack trace: exports.default<.adapter<@eval:680:7
ComputedPropertyPrototype.get@http://localhost:4200/assets/vendor.js:29087:15
get@http://localhost:4200/assets/vendor.js:33959:14
exports.default<.get@http://localhost:4200/assets/vendor.js:46983:14
checkAdapter@eval:814:56
sendEvent@http://localhost:4200/assets/vendor.js:29952:11
exports.default<.trigger@http://localhost:4200/assets/vendor.js:46262:7
messageReceived/<@eval:3603:9
wrap/<@eval:3633:18
Backburner.prototype.run@http://localhost:4200/assets/vendor.js:10829:18
run@http://localhost:4200/assets/vendor.js:34263:12
wrap@eval:3631:14
messageReceived@eval:3602:7
init/<@eval:3594:11
_messageReceived/<@eval:131:9
_messageReceived@eval:130:7
_listen/</<@eval:419:11
Backburner.prototype.run@http://localhost:4200/assets/vendor.js:10829:18
run@http://localhost:4200/assets/vendor.js:34263:12
_listen/<@eval:406:9
"
  • Chrome
VM131:96 Ember Inspector has errored.
This is likely a bug in the inspector itself.
You can report bugs at https://github.com/emberjs/ember-inspector.
Error message: Cannot read property 'set' of undefined
Stack trace: TypeError: Cannot read property 'set' of undefined
    at Class.<anonymous> (<anonymous>:680:14)
    at ComputedPropertyPrototype.get (http://localhost:4200/assets/vendor.js:29087:28)
    at Object.get (http://localhost:4200/assets/vendor.js:33959:19)
    at Class.get (http://localhost:4200/assets/vendor.js:46983:38)
    at Class.checkAdapter (<anonymous>:814:61)
    at Object.sendEvent (http://localhost:4200/assets/vendor.js:29952:18)
    at Class.trigger (http://localhost:4200/assets/vendor.js:46262:25)
    at <anonymous>:3603:16
    at Class.<anonymous> (<anonymous>:3633:18)
    at Backburner.run (http://localhost:4200/assets/vendor.js:10829:25)warn @ VM131:96handleError @ VM131:153(anonymous function) @ VM131:3635run @ ember.debug.js:294run @ ember.debug.js:23728wrap @ VM131:3631messageReceived @ VM131:3602(anonymous function) @ VM131:3594(anonymous function) @ VM131:131_messageReceived @ VM131:130(anonymous function) @ VM131:324run @ ember.debug.js:294run @ ember.debug.js:23728(anonymous function) @ VM131:323

Is this by design or you think truly an Inspector issue -- it does run correctly for the rest of my ember apps.

Thanks!

Petros

Resource blueprints incorrect for pods structure

I'm using the basic pods structure and using the ember-cli resource generator. With pods enabled, the generated files are placed in the right locations. However, the import file paths are not correct. Below is a diff from the generated files to the needed files for the role resource.

My generated file structure:

▾ app/
  ▸ components/
  ▸ helpers/
  ▾ initializers/
      role.js
  ▾ role/
      adapter.js
      model.js
      roles.js
      route.js
      serializer.js
  ▸ styles/
  ▸ templates/
    app.js
    index.html
    router.js

Diffs:

diff --git a/app/initializers/role.js b/app/initializers/role.js
index d801f44..c0c04f5 100644
--- a/app/initializers/role.js
+++ b/app/initializers/role.js
@@ -1,7 +1,7 @@
-import Service from '../services/roles';
-import Model from '../models/role';
-import Adapter from '../adapters/role';
-import Serializer from '../serializers/role';
+import Service from '../role/roles';
+import Model from '../role/model';
+import Adapter from '../role/adapter';
+import Serializer from '../role/serializer';

 export function initialize(registry, application) {
   application.register('model:roles', Model, { instantiate: false, singleton: false });
diff --git a/app/role/adapter.js b/app/role/adapter.js
index 446d104..6fc905b 100644
--- a/app/role/adapter.js
+++ b/app/role/adapter.js
@@ -1,4 +1,4 @@
-import ApplicationAdapter from './application';
+import ApplicationAdapter from '../adapters/application';
 //import config from 'genus-ember/config/environment';

 export default ApplicationAdapter.extend({
diff --git a/app/role/model.js b/app/role/model.js
index 1c89dea..035c8c9 100644
--- a/app/role/model.js
+++ b/app/role/model.js
@@ -1,5 +1,5 @@
 import Ember from 'ember';
-import Resource from './resource';
+import Resource from 'ember-jsonapi-resources/models/resource';
 import { attr, hasOne, hasMany } from 'ember-jsonapi-resources/models/resource';

 export default Resource.extend({
diff --git a/app/role/roles.js b/app/role/roles.js
index f80d4c3..9b5ed29 100644
--- a/app/role/roles.js
+++ b/app/role/roles.js
@@ -1,4 +1,4 @@
-import Adapter from '../adapters/role';
+import Adapter from '../role/adapter';
 import ServiceCache from '../mixins/service-cache';

 Adapter.reopenClass({ isServiceFactory: true });
diff --git a/app/role/serializer.js b/app/role/serializer.js
index 3a37af5..e5494cf 100644
--- a/app/role/serializer.js
+++ b/app/role/serializer.js
@@ -1,3 +1,3 @@
-import ApplicationSerializer from './application';
+import ApplicationSerializer from '../serializers/application';

 export default ApplicationSerializer.extend();

Why doesn't a new instance of a resource have the injected service?

I have a route like this:

import Ember from 'ember';
import Resource from 'scoreboard-www/models/game';

export default Ember.Route.extend({
  model: function() {
    return Resource.create({isNew: true});
  }
});

I noticed that the instance that is created by model() does not have the injected service defined. But, instances created by deserialize() (via this.container.lookup(factoryName).create({})) do have the service defined. I looked through the code but couldn't see why this would be. Any idea?

Move Resource#updateRelationship to a mixin

Resource instance methods are mainly meant to operate on the local representation of the resource's data; attributes and relationships (identity objects- type/id). And to speak JSON to the API, the resource's Service (adapter + cache) takes on that role.

The updateRelationship includes a call to the service's patchRelationships method which provides a short cut to editing a model instance and persisting the relationship changes.

By moving any 'persistence' methods into a mixin the Resource will only have methods that operate on it's attributes and relationships without any expectation of providing an ORM like interface.

The Resource is not intended to have any ORM like responsibility. But as a convenience and example of adding that custom behavior, a mixin for persisting relationships in one step would be nice.

Typically editing and persisting a relationship change to a resource instance could be a two step process, one change on the model and one call to the service…

group.addRelationship('users', user.id);
group.get('service').createRelationship(group, user.get('type'), user.id)

Ideally the developer can implement custom methods on their ResourceType prototypes (in app/models) to implement any one-step changes since the ResourceType instance does have it's service injected.

For more details on editing relationships and persisting see: https://github.com/pixelhandler/ember-jsonapi-resources/wiki/Relationship-Editing

[Question] Working with Katharsis dialect for included resources, sorting, and sparse fieldsets

Katharsis implements the JSONAPI spec (almost entirely) but does differ on the URL structure for included resources, sorting, and sparse fieldsets. Some examples at the bottom, documentation here

I'm curious if it would be possible to get such a structure working at all with ember-jsonapi-resources, and if so what are the good, better, and best strategies for doing that. I'm also curious that if any of these strategies involve modifying ember-jsonapi-resources, if the project would be interested in supporting the Katharsis dialect.

Simple Examples
Inclusion of related resources

GET /tasks/?include[tasks]=project

Sorting

GET /tasks/?sort[tasks][name]=asc

Sparse fieldsets

GET /tasks/?fields[tasks]=name

[question] Make related-proxy computed property volatile?

The hasOne and hasMany helpers create a computed property that returns a proxy object. This proxy object is then cached and used for every subsequent get of that relation. This means that either related-proxy.promiseFromCache or service.findRelated is always used. Which means:

  • Cache is only used when it has contains the related resources on proxySetup and then cached. Making it impossible to use the related-proxy to query the server for relations afterwards.
  • The reverse: Cache is never used if it did not contain the related resources on proxySetup. Subsequent gets of that relation will always query the server.

I can't easily imagine this is by design. I think it mostly ends up being service.findRelated, so in most use-cases everything works fine. But I ran into this when I wondered why resources that were included in previous server responses were being fetched again.

I think an easy "fix" would be to add .volatile() to the Ember.computed we return in the hasOne and hasMany helpers. I don't see any impact other than performance (which could very well be significant).

There might be some other mechanisme in place that is supposed to provide this functionality (look for relation resources in cache first), maybe through the PromiseProxyMixin? But I don't think so/can't find any.

Cheerio.

Singular resources

Hi again Bill,

So I'm trying to get a me resource going, adapting a /me endpoint on the API returning the current user.

I generated a resource with ember g resource me, and singularized all references to 'mes' into 'me' on the intializer and service/model/adapter/serializer files. Here's the initializer:

import Service from '../services/me';
import Model from '../models/me';
import Adapter from '../adapters/me';
import Serializer from '../serializers/me';

export function initialize(container, application) {
  const adapter = 'service:me-adapter';
  const serializer = 'service:me-serializer';
  const service = 'service:me';
  const model = 'model:me';

  application.register(model, Model, { instantiate: false, singleton: false });
  application.register(service, Service);
  application.register(adapter, Adapter);
  application.register(serializer, Serializer);

  application.inject('service:store', 'me', service);
  application.inject(service, 'serializer', serializer);
}

export default {
  name: 'me-service',
  after: 'store',
  initialize: initialize
};

And the adapter:

import ApplicationAdapter from './application';
import config from 'client/config/environment';

export default ApplicationAdapter.extend({
  type: 'me',

  url: config.APP.API_HOST + 'me'
});

On the route I'm trying to fetch it in the model like this:

import Ember from 'ember';
import AuthenticatedRouteMixin from 'simple-auth/mixins/authenticated-route-mixin';

export default Ember.Route.extend(AuthenticatedRouteMixin, {
  model() {
    return this.store.find('me', {});
  }
});

But the store still looks for a 'mes' service:

Error while processing route: dashboard mes service not initialized Error: mes service not initialized

Not sure if this is a bug or just not implemented yet (given JSONAPI::Resources has a json_resource for singleton resources, I figured this would be supported in EJR as well), or whether I'm missing something. Let me know also if this is more of a SO or slack question really... =D

ember-simple-auth integration

I noticed my app wasn't sending the authorization header when creating a resource, and after some digging I got it going by overriding ApplicationAdapter#fetchOptions in the resource adapter, making it lookup the access token in ember-simple-auth's session:

fetchOptions(options) {
    let isUpdate;
    options.headers = options.headers || { 'Content-Type': 'application/vnd.api+json' };
    // const authHeader = window.localStorage.getItem('AuthorizationHeader');
    const simpleAuthSession = JSON.parse(window.localStorage.getItem('ember_simple_auth:session'));
    const accessToken       = simpleAuthSession.secure.access_token;
    const authHeader        = 'Bearer ' + accessToken;

    if (authHeader) {
      options.headers['Authorization'] = authHeader;
    }
    if (typeof options.update === 'boolean') {
      isUpdate = options.update;
      delete options.update;
    }
    return isUpdate;
  }

I'm sure there must be a better way :) Beginning to get familiar with ember-jsonapi-resources, and I'm really a rubyist still grokking ember. I'll run this by ember-simple-auth's author tomorrow (I work with him), to see if he has any suggestions.

Thought it worth bringing up, as people using EJR might be using ember-simple-auth as well, and this could get the ball rolling for a proper solution.

Looking for a new maintainer

I used this for about a couple years at my old job. I personally don't have any production app using this (other then my personal blog website).

Maintenance needs:

  • Update and test when new Ember.js stable releases land.
  • Lead future development and improvements.
  • Update to docs and guides when changes warrant updates.

changedAttributes and changedRelationships not live.

In the current implementation, changes are tracked in objects, which computed properties can not track sufficiently. Computed properties like changedAttributes do not update live, and therefor can not be used for changing state in a template for example.

I think we can resolve this by tracking changes in an array, keep a list of keys that have changed (do not match their previous value).

I will send in a PR next week for this, but wanted to give the chance to discuss this in an issue, since I might have overlooked something that either does allow tracking the dirty state of a Resource, or a reason to not list changed keys in an array.

Cheers.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.