Emberfire read data from database that already exists - ember.js

I am learning to use emberfire but I am having trouble reading data from a database that already exists. In other words, I have an iOS app that uses a firebase database. Data is constantly being changed by users on the iOS app. I am now trying to make a web app, using emberfire, that will read from the same firebase database as the one that the iOS app uses.
The problem is, when I try to use
import Ember from 'ember';
export default Ember.Route.extend({
model() {
return this.store.findAll('users');
}
});
nothing is found. I am wondering if this is because the data was not written to the database from the emberfire app and therefore it is not aware of the data that the iOS app has written to the database. Does this make any sense? Shouldn't the emberfire app know to search the database for 'users' if it doesn't have any saved in the local this.store ?

try:
return this.store.findAll('user');
the problem may be in plural 'users'

You could try using this.store.query('users', {}); and see if it helps.
Otherwise I'd suggest double and triple checking that you are logged in properly in your Ember app (unless your Firebase rules make your data public).

Related

Elesticsearch and Emberjs

I'm trying to wire EmberJS with ElasticSearch. So far, I've read most of the Ember documentation, and found out this adapter for ElasticSearch.
The problem is I can't figure out how to use it (i.e. configure it so that when I call store.save(), my model is sent to ES.
What I have ATM is a newly created project with Ember generator (ember new ), and a generated controller, router, model, etc. My problem is that the Ember document explains how to customise adapters, but not how to use them (or I missed that part). The ES adapter's documentation says :
var App = Em.Application.create();
App.store = DS.Store.create({
revision: 4,
adapter: DS.ElasticSearchAdapter.create({url: 'http://localhost:9200'})
});
which implies to create a Store, whereas I can only see ways to extend it in the Ember documentation. Furthermore, I already have a Store in my application.
So the questions are:
do I need to override the store creation to replace it with the ES one (and where to do that) OR
do I need to extend the existing one, and in this case, how should I do that ?
Also, when it says:
First, load the ember-data/lib/adapters/elasticsearch_adapter.js file
in your application.
where and how that should be done ?
On your first questions/s
do I need to override the store creation to replace it with the ES one
(and where to do that) OR do I need to extend the existing one, and in
this case, how should I do that ?
You're onto the right track in the second part, you will need extend the existing one, but not the store, the adapter in this case.
So if you're using ember-cli, which according to this:
What I have ATM is a newly created project with Ember generator (ember
new )
It seems that you are and so you'll application folder structure should be like this:
app ->
adapters(you need to generate/create this)
components
controllers
models
routes
serializers
services
styles
templates
And now we can answer:
how should I do that ?
If you do not have the adapters folder yet, which you probably don't, just run ember generate adapter application or create a folder adapters, and a file application.js for that folder.
And that then finally leads us to a part of your last question.
load the ember-data/lib/adapters/elasticsearch_adapter.js file in your
application. where and how that should be done ?
import ElasticSearchAdapter from 'ember-data/lib/adapters/elasticsearch_adapter'
export default ElasticSearchAdapter.extend({
})
Now the possible bad news, that adapter is likely very outdated, as it the repository's last commit was 27 Dec 2012.

How to unload a record in Ember 2.3.0?

I am upgrading an Ember 1.13.0 application to Ember 2.3.0 and I'm facing a little issue where I am unable to unload a record from the Data Store without causing Ember to make a HTTP request. I do not want to delete the record in the server. I simply want to remove it from Ember Data Store.
I was using the following Ember DS.Store API: http://emberjs.com/api/data/classes/DS.Store.html#method_unloadRecord in Ember 1.13.0 and it worked fine. Sample:
this.store.find('post', 1).then(function(post) {
this.store.unloadRecord(post);
});
After upgrading to 2.3.0, when I monitor the network tab in Chrome, Ember is making a GET request to find the record and then unload it. Because it fails to find (our server does not have an API to match this call), it doesn't unload the record and the changes don't appear in the UI.
I tried to fix this by instead doing something like:
this.store.peekRecord('posts', 1).then(function(post) {
this.store.unloadRecord(post);
});
but this doesn't seem to work. What is the right way to unload a record from Ember Data without making HTTP calls? Thanks.
Ember data automatically reloads records to keep them in sync with server. So findRecord() resolves immediately, but in background it makes request to the server and update values when it returns. This behavior was changed in ember-data 1.13.0 and is described in toc_new-adapter-hooks-for-better-caching.
The issue with peekRecord is that peek* methods just asks store and thus don't need to return promise. Therefore your code should look like this:
const store = this.get('store');
const post = store.peekRecord('posts', 1);
if (post) {
store.unloadRecord(post);
}

Custom Ember Api Endpoint

I am trying to figure out how to get data from a custom api. I am using Ember 1.8.1, Ember Data 1.0.0-beta.12 and Ember CLI
In my router i have the following resource
this.resource("communities", {path: '/communities/:community-id/follow-ups'}, function() {});
I have my model defined for the correct response. In my communities router I am trying to get the data from the api like so
this.store.find('community', params['community-id']);
The problem I am having is that I am trying to retrive data from the api endpoint
/communities/{community-id}/follow-ups
But the app is trying to grab the data from
/communities/{community-id}
How do I define the custom resource route to pull from the follow-ups
The router path isn't going to change where the API makes the call to, that just helps Ember change the browser path.
You might want to consider using an adapter if you really need it to hit .../follow-ups.
You'd want to make a CommunitiesAdapter I think. ember g adapter communities, or community, not sure offhand.
And I think the function on it you're looking for is pathForType.
Check it out at http://guides.emberjs.com/v1.10.0/models/customizing-adapters/
You can create a custom adapter for your model in particular but deep nesting on routes can be tricky in Ember and not worth the time if you are in a rush.
Try setting the model of the route directly with a get json
App.NAMERoute = Ember.Route.extend({
model : function(params){
return Ember.$.getJSON(window.apiHost+'/communities/'+params.group_id+'/follow-ups');
}
});
Sometimes simple solutions is what you need

How do I access the URL that Ember Data will PUT to?

I'm adapting an old JS (no framework) + Rails app as an Ember learning exercise. The idea of the application is that I'm producing a pdf from some data input. In the initial version, there was no user persistence - you could modify the data provided to you in the tables, and then download the PDF of it.
As part of this, I decided to run with a decidedly non-standard ember framework - I'm essentially using Ember Data to load the initial value of the tables. Ember has been a really natural fit for the models I have on the Rails side, and it's made a lot of the more complicated calculations a lot easier. The issue I have is that my initial idea was that when I came to download the PDF, I'd respond to the "save" action on Ember Data with binary data (with an application/pdf header), which I could then use something like FileSaver.js to serve up to the client. Then, I found that EmberData needs JSON return value.
So I base64 encoded my PDF response and fired it back..but it didn't fit the model schema. I thought I'd then do a manual AJAX save -
CalculateYourTV.RostersShowController = Ember.ObjectController.extend({
actions:{
download: function(){
var roster = this.get("model");
var team = roster.get('team');
return this.ajax('*URL GOES HERE*', record.toJSON(), "PUT").then(function(data) {
console.log('called')
console.log(data)
});
},
}
})
And this is where I'm currently stuck. Is there any way to access the URL that EmberData is posting to? I could hard-code a route in the Rails side of things, but I don't like hardcoding routes in here, and I'd like to keep it as reusable as possible (I'm planning to eventually allow data persistance).
Just open chrome dev tools (or firebug) and monitor what's going on in the network tab. You should see any ajax request your application sends out, including the EmberData's save request.
You can change the URL that a specific model will hit by creating custom Ember Data adapters per model.
For example, say you have a person model that needs to not hit the default /persons URL.
App.PersonAdapter = App.ApplicationAdapter.extend({
pathForType: 'special/custom/endpoint/for/folks'
});
That said, Ember Data may not be the best tool here for your PDF "model". You can always use Ember Data for the majority of your models, but use a quick $.ajax for other stuff that doesn't fit your definition of a true model.
You can ask the adapter to build a URL for you -
adapter = #store.adapterFor('application')
url = adapter.buildURL(type, id)
where type is the name of the model, and id is its id.
If want to look up the adapter directly in the container it is
#container.lookup('adapter:application')

How to make the Ember Local Storage Adapter (LSAdapter) work with the Ember REST Adapter?

I would like to take advantage of both the Ember Local Storage Adapter (LSAdapter) and the Ember REST Adapter (RESTAdapter), so that there is a centralized database for all the users while avoiding sending an Ajax request for each user action.
Specifically, I would like to:
Populate the LSAdapter with data from the server.
All changes users make are updated to the LSAdapter. (I know how to do this step)
(In preparation for #3, I can have a model that saves a log in LSAdapter of all the updates)
Once in n minutes, the LSAdapter update data are sent back to the server.
My backend server is NOT Rails, so please make the answers generic.
Is it possible to use BOTH LSAdapter and RESTAdapter in an Ember app? If so, please provide code sample of how to set it up.
I would also appreciate if you provide code sample for steps 1 and 3, basically, how a database can talk to the local storage and vice versa.
If it's not possible to have both LSADapter and RESTAdapter, what can I do to accomplish steps 1 and 3?
The only get around I can think of is to set up the Ember app store as a RESTAdapter, but then call Web Storage localstorage directly in my app, not calling it from LSAdapter at all. Let me know if there is an easier or built-in way.
After reading Ember data's DS.Store comments, it looks like it might be possible to use 2 adapters at once:
You can retrieve models from the store in several ways. To retrieve a record
for a specific id, use DS.Model's find() method:
var person = App.Person.find(123);
If your application has multiple DS.Store instances (an unusual case), you can
specify which store should be used:
var person = store.find(App.Person, 123);
I will update this answer if I try it out and get it working.
Update 1:
Check out the code in UPDATED for Additional question where both FixtureAdapter and RestAdapter are called.
//define your main adapter as usual
App.Store = DS.Store.extend({
revision: 13,
adapter: DS.RESTAdapter.create({
url: app.apiUrl,
namespace: app.apiNamespace
})
});
//App.Product for example will use the rest adapter
App.Product = DS.Model.extend({
name: DS.attr('string'),
});
App.Somemodel = DS.Model.extend({
name: DS.attr('string'),
});
//App.Somemodel for example will use the fixture adapter
App.Store.registerAdapter('App.Somemodel', DS.FixtureAdapter);