Git Product home page Git Product logo

ember-pouch's People

Contributors

akatov avatar backspace avatar bernardtolosajr avatar brianmbutler avatar broerse avatar brunopedroso avatar devinrhode2 avatar dweremeichik avatar fed03 avatar flyrev avatar fsmanuel avatar jacobq avatar jkleinsc avatar jlami avatar larsjk avatar leo avatar locks avatar lukemelia avatar mattmarcum avatar mize avatar nolanlawson avatar ntodd avatar oleroel avatar perlun avatar phantomphildius avatar rsutphin avatar scandinave avatar simonexmachina avatar stevebest avatar tabeth 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  avatar  avatar  avatar  avatar  avatar

ember-pouch's Issues

Bidirectional hasMany relationships are not loadable/saveable from the many side

The default behavior of DS.JSONSerializer is to not serialize the many side of bidirectional hasMany relationships. See emberjs/data#2494 for links to discussion about this.

The upshot for ember-pouch is that the contents of a bidirectional hasMany relationship isn't saved or loaded when working from the many side. E.g., say you have these models:

// app/models/person.js
export default DS.Model.extend({
  sandwiches: DS.hasMany('sandwich', { inverse: 'owner' })
});

// app/models/sandwich.js
export default DS.Model.extend({
  owner: DS.belongsTo('person')
});

In this case you won't be able to load or save a person's sandwiches from the person. (You will be able to if you remove owner from sandwich, though.)

The workaround for this that other similar adapters use (ember-localstorage-adapter, ember-indexeddb-adapter) is to provide a serializer which forces these associations to be serialized on the hasMany side (as well as the belongsTo side). I'm doing this now in my own application to work around this issue.

Unfortunately this requires copying a bunch of code from JSONSerializer (hence emberjs/data#2494). It also duplicates the information about the relationship, requiring both sides to be saved manually whenever the relationship changes.

I'm not sure if there's a practical better solution. It appears that the ember-data solution is to have the server use different serializations for reads vs. writes, but that doesn't work for a local database. One idea I had was that the adapter could look up the IDs for the hasMany relationship dynamically — since all the data is local this might work, but it also might be complex to get right.

EventEmitter memory leak warnings since update to 1.1.3

The incorporation of the call to changes is causing these warnings for me:

(node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit.

I see this was discussed in the PouchDB repository, but the resolution there doesn’t apply, since I’m ember-pouch is starting the change listener, rather than me.

I verified that this was the cause of the warning by removing the call to changes: the warning went away.

The warning comes as soon as I load anything from PouchDB, so the pull request I just made, #24, doesn’t help, since it only applies when the application is being destroyed.

Slow load times on initial boot of application

I've got a very basic application which uses Pouch/CouchDB, and I've got Ember Pouch successfully pulling down and loading documents on newly connecting clients. I'm finding the initial population of data and updating of the page view to be pretty slow though. I've seen discussion of loading db.allDocs to be painful for applications with lots of records, but I only have 25 in my app (including the design doc), and it's not going to grow by more than a few documents every several months. Yet it takes upwards of 3-4 seconds on new clients to display any data. My production site is being hosted on Cloudant, and my local instances don't do much better.

Here's my adapter. Is there anything obvious I can be doing to speed up load times? I've tried using only the db.allDocs, or the db.changes, but I can't really find any difference between the two in results, and the docs aren't super clear (which I'll get to in a second).

I have a static page (hard coded into the template file) that loads to begin with. Ideally, I'd like to start downloading a few records in the background while folks are reading that, but the network doesn't try to acquire the Pouch copy until I've switched routes. Setting my index page to retrieve data it doesn't use just to initiate the PouchDB creation seems like bad form, but I don't see any scenarios documented for bootstrapping specific content, only broad strokes examples for grabbing all docs, a single doc by id, or changed docs.

What I'm finding though is that there's not really any great descriptions of what each option means, or moreover, the meanings are muddled. For instance, when I get allDocs, am I getting the current version of every doc, or am I getting every revision of every doc? From what I'm seeing in my console, I'm receiving the latter (519 requests and 90MB of data). When I request db.changes, I would presume I'm only receiving items that have changed since my last visit, and expect it to do nothing on my first visit as everything should new to me for the first visit, but that's not the case.

I think there are a few user scenarios that might be helpful to add to the docs, so that people starting out (like myself) have a foothold on what to use where. There are great examples that I've copied from, which have been quite helpful getting set up, but there's not a ton out there on the "whys" and "what fors". Going back to the CouchDB docs don't really help with these problems as they don't get into any more detail either. I would be happy to contribute a PR to the documentation, but I could some guidance on the above in order to help.

Thanks!

Question about using database per instance

Hi!

In my application I want to have separate database for each Ember model called Project. The project is something like a container for model Todo.

And one of my usecases is just to show all todos for project. But I have separate db for each of them.
So how can I toggle between my dbs "on the fly"?

My idea is to to reopen Todo adapter and redefine db like this:

if (!Ember.isEmpty(project.get('projectDbName'))) {
  var dbName = project.get('projectDbName');
  var db = new PouchDB(dbName);
  var remote = new PouchDB('http://127.0.0.1:5984/%@'.fmt(dbName));

  var doSync = function() {
    db.sync(remote, {
      live: true
    }).on('error', function() {
      setTimeout(doSync, 1000);
    });
  }
  doSync();
  TodoAdapter.reopen({
    db: db
  });
}

But this seems to be not working.

Server side deletion doesn't update store

Hi,

I'm rather new to Ember & Pouch but I've setup a small test project where I list a set of items. Everything like adding and updating seems to work but for single problem, if I delete a document (server-side) the changes aren't reflected until I refresh the page.

I've the afterModel function as per the docs implemented and updating a document server side is reflected on the page. I'm unsure about the issue but a potential problem is that every document on my couchdb has the id in the form "post_2_*" where post is my model name and 2 is (for some reason) always the same for every document. The * part does show some sort of unique identifier.

Significance of number inbetween underscores in ID

Hi,

Firstly, just wanted to let @nolanlawson and other contributors you have done an awesome job putting this together. Was literally a life-saver for us as we are heavy users of Ember with CouchDB/Couchbase Lite/PouchDB! Hopefully we can contribute too in the new year.

As there isn't much chance of a question for this addon getting answered in stackoverflow just yet, hope you dont mind me listing it here.

When a record is saved back to the DB, it gets an ID like this:

staffMember_2_C7BD604D-182C-23A4-A024-7D582F2F396D

I obviously understand the first word is the model and the long ID string is the UUID. But what is the significance of the number 2 between them?

Main reason I ask, is in one particular project we are generating documents from outside ember-pouch too, so I want to make sure I understand all the current conventions.

Thanks again and great work!!!

How to retrieve an attachment's data blob?

It looks like I got attachments saving correctly using an attachment transform. However, when I pull the record back out stub is set to true and data is undefined when I look at the data in my deserializer.

Is there any way to get relational pouch to automatically retrieve attachments? I.e. pass {attachments:true} like you can with regular pouch?

Adding new npm maintainers

I've been slow to respond to issues recently, mostly due to going on vacation for the past few weeks.

I'd hate to see progress stalled on this project due to my own lack of free time, so if the other maintainers could please post their npm usernames here, I'd be happy to add them as npm authors so that they can publish. :)

Conflicts are not currently handled correctly

So this is a problem that occurred to me recently: the changes() feed actually includes conflicting and non-winning leaf revisions, which presumably you don't want to show in a list of DOM elements because it looks like duplicates.

So we will have to add some fancier logic to the changes() feed to check for non-winners. Hopefully we won't need to add any new APIs for conflict resolution, though, because that should be possible via PouchDB itself.

Ember-Data 1.0.0-beta.15 not working with Ember-Pouch?

I don't know for sure if this is a ember-pouch thing but it seems ember-data gives an error on destroyRecord().

json_serializer.js:544 Uncaught TypeError: undefined is not a function

In the serializeAttribute: sub on: snapshot.attr

If I go back to 1.0.0-beta.14.1 all works again

Is there somebody who can confirm Ember-Pouch and destroyRecord() works with Ember-Data 1.0.0-beta.15 ?

I will investigate further.

docs / query about deleted item tombstones and which system introduces them

I'm new to couch and pouch, but this addon was suggested as a way to persist data across page reloads, and so far it seems like a really great solution.

I've noticed tombstones are getting left behind when I use destroyRecord() in ember, e.g.
{_deleted: true, _doc_id_rev: '...'}. I think I know the theory behind these, and would like to know if there's a way to garbage collect them, or disable them, in an app-specific / model-specific fashion.

Also which system introduces the use of tombstones, so I can figure out which docs to read about their semantics: couchdb, pouchdb, relational pouch? I think it'd be an interesting thing to add to the readme for people who need to explore the system's behaviour.

bidirectional relationship makes problems

Here the model:

App.Article = DS.Model.extend({
        title: DS.attr('string'),
        comments: DS.hasMany('comment'),
        rev: DS.attr('string')
});
App.Comment = DS.Model.extend({
        text: DS.attr('string'),
        article: DS.belongsTo('article'),
        rev: DS.attr('string')
});

After save() is the hasMany-assoziation array empty. if I omit article: DS.belongsTo('article'), then the comments-array is filled.

Question about document _id's

Sorry for additional questions, but I am a little confused after reading the docs for both ember-pouch and relational-pouch.

With ember-pouch, are the document id's automatically set to "pokemon_1" or "trainer_2" as mentioned in the README for relational-pouch?

Also, does ember-pouch include the relational-pouch plugin and call the appropriate db.setSchema() methods automatically?

Any way to track requests in progress? For acceptance tests

I was having intermittent failures in my acceptance tests that I was able to fix using this technique of setting a promise on the controller that the test waits for the resolution of. It seems unfortunate to me to add test-specific code to the application, so I’ve been looking into how the andThen acceptance test helper determines when asynchronous operations are complete so it can check the expectations.

I think the key code is here. This line would be helpful if the application were backed by a REST/AJAX database:

// 2. If there are pending Ajax requests, keep polling
if (Test.pendingAjaxRequests) { return; }

Elsewhere, they register to listen for AJAX events and operate on the counter that way:

jQuery(document).on('ajaxSend', incrementAjaxPendingRequests);
jQuery(document).on('ajaxComplete', decrementAjaxPendingRequests);

So, my question, is there a way I can detect an ongoing PouchDB operation and delay the progression of the test until the operation is complete? I looked at PouchDB.on, but it’s apparently only for created and destroyed events.

Maybe there’s a way to include this kind of functionality in ember-pouch to facilitate acceptance tests. Like setting a flag before a call to this.db.rel.find and the like, and unsetting it when the operation completes. Then I could override `setupForTesting' and pretend that a PouchDB operation is an AJAX operation, for the purposes of testing.

Ideally, ember-testing would have a facility where ongoing asynchronous operations can be registered to delay test progression, but I’m not optimistic on that happening.

This may not be something you want ember-pouch to be concerned with, though, understandably.

Deprecation warnings coming from the change watcher with ED 1.13

Reported by @OleRoel in #72:

  • Using store.getById() has been deprecated. Use store.peekRecord to get a record by a given type and ID without triggering a fetch
  • DS.Model#isDirty has been deprecated please use hasDirtyAttributes instead
  • You tried to look up 'store:main', but this has been deprecated in favor of 'service:store'

I think these are all coming from the change watcher.

Can't set up ember-pouch

HI,
I'm new with Ember and so with ember-pouch. I try to set up the adapter but i'm facing some problems. I use Ember 1.11.3, Ember data 1.16.1 with ember-pouch 1.2.5

This is my app/adapter/application.js

import config from '../config/environment';

var remote = new PouchDB(config.remote_couch);
var db = new PouchDB(config.local_couch);
PouchDB.debug.enable('*');
db.sync(remote, {
   live: true,   // do a live, ongoing sync
   retry: true   // retry if the conection is lost
});

export default EmberPouch.Adapter.extend({
  db: db
});

And this is errors:

adapters/application.js: line 3, col 18, 'PouchDB' is not defined.
adapters/application.js: line 4, col 14, 'PouchDB' is not defined.
adapters/application.js: line 5, col 1, 'PouchDB' is not defined.
adapters/application.js: line 11, col 16, 'EmberPouch' is not defined.

I've tried to add this line on top of application.js

import PouchDB from 'ember-pouch';
import EmberPouch from 'ember-pouch';

but i've got this error :

Could not find module `ember-pouch` imported from `myapp/adapters/application`" "requireFrom@http://localhost:4200/assets/vendor.js:119:1

One idea what i did wrong?

Storing Data requires at least 1 page refresh

On my new site which implements ember-pouch, I encounter the issue that upon first load of page, an error occurs:

too much recursion vendor-f49700c71897d8185469b878fc3a8c2a.js:36
AbortError vendor-f49700c71897d8185469b878fc3a8c2a.js:35
Error: once called more than once vendor-f49700c71897d8185469b878fc3a8c2a.js:37
AbortError vendor-f49700c71897d8185469b878fc3a8c2a.js:35
Error: once called more than once vendor-f49700c71897d8185469b878fc3a8c2a.js:37
AbortError vendor-f49700c71897d8185469b878fc3a8c2a.js:35
Error: once called more than once vendor-f49700c71897d8185469b878fc3a8c2a.js:37
AbortError vendor-f49700c71897d8185469b878fc3a8c2a.js:35
Error: once called more than once vendor-f49700c71897d8185469b878fc3a8c2a.js:37
AbortError vendor-f49700c71897d8185469b878fc3a8c2a.js:35
Error: once called more than once vendor-f49700c71897d8185469b878fc3a8c2a.js:37
AbortError vendor-f49700c71897d8185469b878fc3a8c2a.js:35
Error: once called more than once vendor-f49700c71897d8185469b878fc3a8c2a.js:37
AbortError vendor-f49700c71897d8185469b878fc3a8c2a.js:35
Error: once called more than once vendor-f49700c71897d8185469b878fc3a8c2a.js:37
AbortError vendor-f49700c71897d8185469b878fc3a8c2a.js:35
Error: once called more than once vendor-f49700c71897d8185469b878fc3a8c2a.js:37
AbortError vendor-f49700c71897d8185469b878fc3a8c2a.js:35
Error: once called more than once vendor-f49700c71897d8185469b878fc3a8c2a.js:37
AbortError vendor-f49700c71897d8185469b878fc3a8c2a.js:35
Error: once called more than once vendor-f49700c71897d8185469b878fc3a8c2a.js:37
AbortError vendor-f49700c71897d8185469b878fc3a8c2a.js:35
Error: once called more than once vendor-f49700c71897d8185469b878fc3a8c2a.js:37
AbortError vendor-f49700c71897d8185469b878fc3a8c2a.js:35
Error: once called more than once vendor-f49700c71897d8185469b878fc3a8c2a.js:37
AbortError vendor-f49700c71897d8185469b878fc3a8c2a.js:35
Error: once called more than once vendor-f49700c71897d8185469b878fc3a8c2a.js:37
AbortError vendor-f49700c71897d8185469b878fc3a8c2a.js:35
Error: once called more than once vendor-f49700c71897d8185469b878fc3a8c2a.js:37
AbortError vendor-f49700c71897d8185469b878fc3a8c2a.js:35
Error: once called more than once vendor-f49700c71897d8185469b878fc3a8c2a.js:37
AbortError vendor-f49700c71897d8185469b878fc3a8c2a.js:35
Error: once called more than once vendor-f49700c71897d8185469b878fc3a8c2a.js:37
AbortError vendor-f49700c71897d8185469b878fc3a8c2a.js:35
TypeError: setting a property that has only a getter vendor-f49700c71897d8185469b878fc3a8c2a.js:36
uncaught exception: {"status":500,"name":"error","message":"AbortError"}
TypeError: setting a property that has only a getter

But on subsequent page loads, the data is correctly retrieved and stored in the client (in Chrome; in Firefox, the page never retrieves data).

Perhaps this is a pouch-db issue, but my first assumption is that this is something ember-related.

See live example here.

findAll method only returns already loaded records?

Hi,

I bumped into a small issue and I hope you guys can help me.
I’m writing an electron application with ember-cli and ember-pouch.
The scenario is as follows:

I have two routes: /trains and /train/:train_id

When I boot the app from the /trains route I get all the trains, which is good.
When I boot the app from the /train/:train_id route I get that specific train, which is also good, but if I then transition into the /trains route the findAll method of the store only returns that specific train that was already loaded.

Any ideas on this?

For the time being I can work around this issue by implementing:

shouldReloadAll: function () {
    return true;
 }

on the adapter, but this is not desired of course.

Thanks in advance!

Attachment support?

As far as I can make out ember-pouch does not support attachments, is that correct? I saw that relational-pouch does support them, are there any plans to implement them in ember-pouch?

Adapt for ember-data 1.0.0-beta16

Starting in ember-data 1.0.0-beta16, adapters will no longer receive actual records. They will receive snapshots instead. See emberjs/data#2883.

This is a placeholder for any work that's necessary to adapt to this — it's possible that no changes will be necessary.

Authentication implementation

Good day all,

i try to implement authentication in ember-pouch which login & logout but i keep facing problem.

i know there is library named CouchDB Authentication but don't have any idea how to include in the ember project.

your help is highly appreciated

Test with Ember Data test suite

So right now there are automated Travis tests in relational-pouch, but I have no idea what the best practice is for an Ember/Broccoli/Ember Data plugin, so I've just punted.

Really there should be tests, though. It's kind of embarrassing that I have none.

shouldReloadAll will change in Ember Data 2.0

I get this deprecation warning:
Ember Inspector (Deprecation Trace): The default behavior of shouldReloadAll will change in Ember Data 2.0 to always return false when there is at least one "author" record in the store. If you would like to preserve the current behavior please override shouldReloadAll in your adapter:application and return true.
Do we need to change something? Is the new behavior better?

Automatically handle adding rev property?

I noticed that @taras'sember-pouchDB library doesn't require you to add rev properties to each model.

This is the code from his project that handles that: /lib/ember-pouchdb/storage.js.
(storage.js imports Model from /lib/ember-pouchdb/model.js which is the only other file referencing the rev property)

I would imagine there's some good way to automatically handle adding the same string field to every model so a user doesn't have to do this. (and if there isn't a good way that maybe there should be some api added to ember or pouchdb)

How to include in an ember-tools project

Hi,

Im going to implement findQuery() in ember-pouch but the project I need to use it in is being built using ember-tools (which is based on commonJS) and the build process is complaining of missing include files which i cant find in the ember-pouch or relational-pouch repos.

e.g. Error: Cannot find module './reject'

Could anyone suggest the best way to include ember-pouch, relational-pouch and pouchdb in an ember-tools project?

cheers

Switch between CouchDB and PouchDB at runtime?

Is switching between CouchDB and PouchDB at runtime possible with this adapter? I'd like to prompt the user and get permission before pulling their data into the browser.

If not, I might try to create another community CouchDB and/or PouchDB adapter, so any basic advice on how to structure this would be greatly appreciated: one adapter or two and which adapter/serializer to start with (extend)?

Issue with sync

It seems that if the sync is not done ( at least the first one, when the DB is replicated ) ember pouch is not able to read the data.
Might be a bug with pouch-relational as I guess you need to hook inside some events for it to works.

Make changes listener optional

Right now https://github.com/nolanlawson/ember-pouch/blob/master/lib/pouchdb-adapter.js#L10-L24 always runs. I have a different implementation of the change feed and have to modify the source. I'd like to add a flag/option somewhere to specify if this code should run or not.

The code I use for sync following does not reload all records, but tries to discover what happened and to only update what is necessary:

      db.on 'change', (change) =>
        return if change.id.match /^_design\//
        db.setSchema [] unless db.rel # make sure relational pouch is triggered
        {type, id} = db.rel.parseDocID change.id
        console.log 'got change', type, id, change
        record = @get('store').getById type, id # ask store for the record without loading it
        if change.deleted          
          record.unloadRecord() if record?
        else
          #test if the record is known in the store
          if record?
            if record.get('isEmpty') || record.get('isLoading') || record.get('isSaving') || record.get('isReloading')
              record.one 'didLoad', -> Ember.run.next ->
                return if record.get 'isDestroyed'
                try
                  console.log 'reload', record, 'after waiting for being loaded'
                  record.reload()
                catch e
            else
              if change.changes[0].rev == record.get('rev')
                return console.log 'no reload needed because we already have the correct rev (we triggered the change)', record
              console.log 'will reload', type, id, 'because of server change'
              record.reload()
          else
            #record is not known, but may be a match for a findAll
            model = @get('store').modelFor type
            typeMap = @get('store').typeMapFor model
            return unless typeMap.findAllCache? # private property of Ember Data
            console.log 'will load record', id, 'as a findAll on', type, 'exists'
            return Ember.run.later =>
              @get('store').find type, id
            , 500

Sorry for the coffeescript, I hope it inspires others

Serialize to different data format?

I am working with an existing CouchDB dataset where records are structured like this:

{
  "_id": "...",
  "_rev": "...",
  "my_attr": "value",
  "my_other_attr": "value"
}

Ember pouch seems to want my data in this format:

{
  "_id": "...",
  "_rev": "...",
  "data": {
    "my_attr": "value",
    "my_other_attr": "value"    
  }
}

Whilst I like this in principle it's not practical for me to migrate my CouchDB data as there are other clients which depend on the existing format. My question is, do you know of a good way which I can serialize and deserialize data between the two formats?

I'm wondering if there's somewhere I can get inbetween the replication from PouchDB to CouchDB and transform the data? Any help would be greatly appreciated!

Introduction to `ember-pouch` at Global Ember Meetup

@nolanlawson will be giving a talk on Web Workers on April 9th at Global Ember Meetup. Would you like to make it a double feature with an Introduction to ember-pouch talk?

Introduction to talks answer the following 3 questions:

  1. Why was this addon created? (what use case is it trying to address)
  2. How do you use it?
  3. What should the user be aware of?

After the talk, we'll edit the video and submit a PR with a link to the videos in the README. You can see some other Introduction to talks here https://vimeo.com/album/3607049

What do you think?

Deleted conflicts do not propagate between nodes

TL;DR: How do I tell ember-pouch to delete the entire doc (not just the rev) with model.destroyRecord?

I have a simple setup with a list of friends with names. I create a new friend Mike on Client A. It gets synced to Client B. Now I change the name of the friend to Peter on Client B while being offline and parallel I change the name to Arnold on Client A while being online. When Client B gets online again, we have a conflict, it makes sense. A winner will be selected, so far so good.
Now I want to delete this friend. But what happens? The friend does not disappear. The friend will get the name of the "loser" leaf instead. I read that this is intended.
But how do I tell ember/ember-pouch/pouch to delete the entire doc when I click destroyRecord within ember?

Implement queries

Got this request from a user, but I have no idea how to implement it.

I'm currently building a node-webkit application using Ember and Ember-Pouch. It works great to retrieve my model and to add data in the IndexedDB.

When it comes to querying though, I'm getting errors I'm not sure where it comes from.

  1. When I retrive the data, I call this.get('store').find('client'); in the route model. It gets all the records fine. However, if I add details, say this.get('store').find('client', { first_name: 'George' });, it always return an empty set even though George exists.
  2. When I want to query for a specific client from the controller, for instance this.get('store').find('client', { phone: phone_num });, it logs a GET app://cbt/clients?phone=5555555555 net::ERR_FILE_NOT_FOUND. Why is it searching for 'clients' plural while everywhere in my models it's 'client' singular?

I'm not very experienced with Ember-Data yet and I was wondering if my issues where with the Adapter or with Ember-Data.

Related to pouchdb-community/relational-pouch#3.

How to properly create related models

Hello! Thanks for your work on this, I’m happy that Ember Data and PouchDB are closer to working smoothly together.

I’m having trouble understanding how to create related models, which is maybe what #8 was about, but that person’s resolution was unclear to me.

I created a simple example application, which is running here.

Here are the models, representing issues of a magazine and the features within them:

app/models/issue.js:

DS.Model.extend({
  title: DS.attr('string'),
  features: DS.hasMany('feature'),

  rev: DS.attr('string')
});

app/models/feature.js:

DS.Model.extend({
  title: DS.attr('string'),
  issue: DS.belongsTo('issue'),

  rev: DS.attr('string')
});

Nothing special.

My question is: is it expected behaviour that an issue is always stored in the database with features as an empty array? When you visit the example application, you can see that it thinks, upon load, that the lone issue has 0 features. When you click the Load features button, it runs store.find('feature'), and suddenly the feature is connected to its parent issue.

There’s a button to print the contents of the PouchDB, here’s example output:

{
    "total_rows": 2,
    "offset": 0,
    "rows": [
        {
            "id": "feature_2_4CDC71E9-08EC-2E42-B167-F4B3B495DBA4",
            "key": "feature_2_4CDC71E9-08EC-2E42-B167-F4B3B495DBA4",
            "value": {
                "rev": "1-c9bd4bfcd6c416a54c5783ceaac787b1"
            },
            "doc": {
                "data": {
                    "title": "A feature",
                    "issue": "A6A770A8-E416-CB0B-900A-58CF2809A369"
                },
                "_id": "feature_2_4CDC71E9-08EC-2E42-B167-F4B3B495DBA4",
                "_rev": "1-c9bd4bfcd6c416a54c5783ceaac787b1"
            }
        },
        {
            "id": "issue_2_A6A770A8-E416-CB0B-900A-58CF2809A369",
            "key": "issue_2_A6A770A8-E416-CB0B-900A-58CF2809A369",
            "value": {
                "rev": "2-c05d1fb71749477e6c695283b7bac761"
            },
            "doc": {
                "data": {
                    "title": "An issue",
                    "features": []
                },
                "_id": "issue_2_A6A770A8-E416-CB0B-900A-58CF2809A369",
                "_rev": "2-c05d1fb71749477e6c695283b7bac761"
            }
        }
    ]
}

Maybe I am constructing the models in the wrong way? In my real application, I’m constructing test models in acceptance tests. For the example application, I made an initialiser to do the same:

{
  name: 'data-populator',
  after: 'store',

  initialize: function(container, application) {
    application.deferReadiness();

    var store = container.lookup('store:main');

    var issues = store.find('issue');
    issues.then(function() {
      if (issues.get('length') == 0) {
        var issue = store.createRecord('issue', {title: 'An issue'});

        issue.save().then(function() {
          var feature = store.createRecord('feature', {title: 'A feature'});
          issue.get('features').pushObject(feature);
          feature.save();
          issue.save().then(function() {
            application.advanceReadiness();
          });
        });
      }
      else {
        application.advanceReadiness();
      }
    });
  }
}

I’ve tried a variety of ways of constructing the models, like passing in the issue when creating a feature:

var feature = store.createRecord('feature', {issue: issue, title: 'A feature'});

and many other variations, but never have I seen the features array be anything but empty in the database.

I’ve been using weird workarounds like pre-loading all features in the issues route, and similarly for other related models, but I suspect I’m just missing something.

Documentation on how to handle conflicts with ember-pouch

Being banging my head against this problem, has it seems there is no good way to do that ( where to put a hook to get the conflict notification, and what to do ).
For the what to do part, it seems fairly simple using pouchdb documentation ( even if they are not using any sample of three way merging ) but I think a complete sample would be a good idea.

I try to override the save method inside my models, and use :

save() {
    _super().then( 
        (result) => { return result }, 
        (err) => { return this.handleConflicts() }
    )
}

But when I arrive there, to get the conflicts for the document I need to re-generate the id format that relation pouch is using, and it seems a bit of a bad idea.

If anyone have some pointer to that, that would be super cool.

Check the rev to avoid unnecessary reloads in change watcher

The change watcher calls reload when a change is encountered for a record that is in ember-data's store cache. However, the change notifier in PouchDB notifies for all changes, including ones that originated in the ember app. Compare the rev of the change to the rev the store knows about and avoid reloading for those changes.

Originally suggested by @broerse in comments on #50.

Error: Cannot set property 'id' of undefined

If you do:

  • "ember build" on the now perfect working example
  • go to the "dist" folder
  • run a server like "http-server" (npm install http-server)
  • go to localhost:8080

You get an error "Error while processing route: posts.index Cannot set property 'id' of undefined TypeError: Cannot set property 'id' of undefined"

The error points to the obj.id line in your code:

  function transformOutput(typeInfo, pouchDoc) {
    var obj = pouchDoc.data;
    obj.id = deserialize(pouchDoc._id);
    obj.rev = pouchDoc._rev;
    return obj;
  }

If you run with "ember server" and not the "ember build" version the code works fine.

If you can find the time take a look.

Relationship in model generates "Cannot read property ‘has’ of undefined' exception" with Ember Data 1.13.0

When I use a relationship in my model like:

import DS from "ember-data";
import { Model } from 'ember-pouch';

var Modelname = Model.extend({
    name: DS.attr('string', {defaultValue: ""}),
    pages: DS.hasMany('page', {async: true, serialize: true})
});

export default Modelname;

The code is borrowed from @broerse from where the discussion started. The problem seems to be introduced with verson 19.1 of ember-data as brianmbutler states in the original discussion.

The same exception pops up with DS.belongsTo.

With help of the Chrome debugger I was able to find the culprit in the init method.

...
if (!Ember.get(type, 'attributes').has('rev')) {
...

https://github.com/nolanlawson/ember-pouch/blob/master/addon/adapters/pouch.js#L82

expects type to be a model object but gets a string when a relationship is defined inside your model.

Conflicts

Does ember-pouch deal with conflicts?

At the moment, if I update from one client then attempt to update from another, it just does nothing. No error message at all. I'm not really sure what's going on? Maybe you could point me in the right direction?

ember-cli addon

Hi,
I done some initial work in making the project in to a proper ember-cli addon. With some refactoring on the way (could not help myself :)).

https://github.com/tchak/ember-pouch/commit/d573a41226a81aa5148ec04d330193a33c2aebbf

Would you be interested in a PR ? Or do you prefer to keep your less opinionated project as is?
We can probably find some middle-ground. Like I can extract some changes in your project and then release ember-cli-pouch wrapper relying on bower build from ember-pouch. Let me know how you fill about it.

Increment ember-pouch version

Can we do a minor version increment to reflect the code changes with the last two or so PRs? When I do a npm install ember-pouch or ember install ember-pouch I still get an old version of ember-pouch which is not identical to the GitHub repo. I guess npm caches the code and doesn't update it until the version number has been incremented. At least their website says "nolanlawson published 3 weeks ago": https://www.npmjs.com/package/ember-pouch

ArrayController SortableMixin not working on store?

I may have this poorly configured, but here is an idea:

Using pouch-find I create an index (because it wasn't working without an index, thought this may help)

db.createIndex({
  index: {
    fields: ['startDate', 'endDate']
  }
}).then(function (result) {
  console.log(result)
}).catch(function (err) {
 console.log(error)
});

Then in the controller for the route:

export default Ember.ArrayController.extend({
  sortProperties: 'startDate',
  filterBy: 'startDate'
});

What am I missing here?

Being able to use the ArrayController seems like it will be a nice alternative to trying to get pouch-find working with relational pouch, but it just doesn't seem to be working properly. All I need is your normal upcoming events list - startDate $gte this morning, sorted by startDate ascending, only showing items with a date (for now). If I wanted to be really messy I could use async sortBy and filterBy to mess with the controller model property.

How would you resolve this issue with ember data?

LightCouch to produce data and ember-pouch to consume

Hi,

We have a Java application which uses LightCouch API to put the data to CouchDB and on browser we use ember-pouch to get the data for viewing.

Our POJO looks like the following
class Blog extends Document {
String title;
Date date;
....
}

When saving the object using LightPouch, the source looks like the following

{
"_id": "post_2_46252996-35A1-E69E-8E1A-753031B32E4D",
"_rev": "1-0371b19fac2a94ab0c8bdf9bb263bdd8",
"title": "",
"date": "2015-08-25T16:36:05.522Z",
"excerpt": "",
"body": "",
"author": "A1D67CD4-984C-4B00-831E-1EC598321435"

}

I notice that ember-pouch (or more precisely relational-pouch) expects the data to be wrapped under data attribute like the following
{
"_id": "post_2_46252996-35A1-E69E-8E1A-753031B32E4D",
"_rev": "1-0371b19fac2a94ab0c8bdf9bb263bdd8",
"data": {
"title": "",
"date": "2015-08-25T16:36:05.522Z",
"excerpt": "",
"body": "",
"author": "A1D67CD4-984C-4B00-831E-1EC598321435"
}
}

This means ember-pouch is not compatible with any CouchDB or PouchDB application due to the relational-pouch layer. Am I right?

Is there any particular reason it is design in such a way?

What can I do to make ember-pouch put the data in the same way as LightCouch (without wrapped in data)?

Regards,
--Nick

find document which does not exist

Finding a document which does not exists leads to an Ember error.

When issuing a find('book', 'abc') relational-pouch returns with {"books":[]} when the abc id is not existing. Ember Data chokes on this response, as the response is not null, so it assumes the data is there. In the end it runs https://github.com/emberjs/data/blob/7db210f29a45d9d874f9f7f52455bcd56ac2320a/packages/ember-data/lib/serializers/rest_serializer.js#L266. As there is no data in the array, primaryRecord will stay undefined and the app will halt.

Question here is, should Ember Data be able to handle an empty list response? Or should Relational Pouch not return an empty response (if it is against the spec)?

My solution was to extend the adapter (sorry coffeescript):

ApplicationAdapter = Adapter.extend
  db: new PouchDB 'mydb'
  find: (store, type, id) ->
    @_super(store, type, id)
    .then (payload) ->
      for type, list of payload
        delete payload[type] unless list?.length > 0
      throw 'Not found' if Ember.keys(payload).length == 0
      payload

The code above allows for a find-or-create statement for example in a Route:

IndexRoute = Ember.Route.extend
  model: ->
    store = @store
    return store.find('opname', 1)
    .catch (reason) ->
      switch reason
        when 'Not found'
          record = store.recordForId 'opname', 1
          record.loadedData() # see https://github.com/emberjs/data/issues/1523
          record
        else throw reason

Another thing which might be integrated in the ember-pouch driver is a set of official errors. Passing 'Not found' string as an error is not too future friendly

Implement error object

The current solution when not finding a record relies on parsing the Error.message to find out which type+id failed to load. Parsing Errors is not a good practise.
My solution would be to introduce an EmberPouchError object, which has a documented api. Ember Data has something similar implemented for validation, see https://github.com/emberjs/data/blob/689b2fa05a1137303d7742faa0d74da2eb9abba5/packages/ember-data/lib/system/adapter.js#L7-L66.

This code would then be possible:

find(...).catch(function(err){
  if (err instanceof EmberPouchError) {
    switch (err.message) {
      case 'Not found':
        console.log('obj not found, type=', err.type, ' id=', err.id);
        return something sane here;
    }
  }
  throw err
})

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.