0
votes

From my Emberjs I am making a custom request to an explore route on my Rails server:

GET http://localhost:3000/explore

I see my JSON response in my Google Chrome network inspector, however, my page isn't rendering anything.

To make the custom request, I have a book adapter:

Book Adapter

import ApplicationAdapter from './application';
import Ember from 'ember';

export default ApplicationAdapter.extend({
  apiManager: Ember.inject.service(),

  findPublishedBooks: function(store, type) {
    let jwt = this.get('apiManager').get('jwt');

    return Ember.RSVP.resolve(
      Ember.$.ajax({
        type: "GET",
        url: this.get('apiManager').requestURL('explore'),
        dataType: 'json',
        headers: {"Authorization": "Bearer " + jwt}
      })
    );
  }
});

Explore Route

model() {
  const adapter = this.get('store').adapterFor('book');
  return adapter.findPublishedBooks();
}

On my Rails side, I have this for my Explore action:

Rails Explore Action

def explore
  books = Book.where(published: true)

  if books.count > 0
    render json: books
  else
    return nil
  end
end

I know I must be doing something wrong, probably on my Ember side.

Update

Explore template

<div class="explore">
  {{#search-field searchAction=(action "searchBooks") clearAction=(action "clearSearchBooks")}}{{/search-field}}
  {{#book-grid books=model class="book-grid" isSearching=isSearching}}{{/book-grid}}
</div>

Book-Grid Template

{{#each books as |book|}}
  {{#link-to "books.book" book}}
    <div class="book">
      <div class="book-cover">
        <img src={{book.cover.cover.url}} alt="{{book.title}} book cover image" width=173 height=231>
      </div>
      <div class="caption">
        {{book.title}}<br>
        <label>by {{book.author.username}}</label>
      </div>
    </div>
  {{/link-to}}
{{else}}
  {{#if isSearching}}
    <label>No search results.</label>
  {{else}}
    <label>There are no published books at the moment.</label>
  {{/if}}
{{/each}}
1
Show your template. Also you realize that you never push the data to the store? Have you considered to use query instead? Usually you shouldn't manually call functions on your adapter.Lux
I have updated my question with the template. Sorry, new to Ember, not sure what I am doing. I have to push to store ? Maybe you know of a better way to achieve what I need?Zhang
Hm, what exactly should findPublishedBooks do? Return like a filtered list of books? Like all books with published:true?Lux
Yes, findPublishedBooks should ask my Rails server to return all books that are published. My Rails route for that is http://localhost:3000/explore which returns a list of books that are published.Zhang

1 Answers

1
votes

I think you need to understand that with your code you basically work around the ember-data store. For ember-data to work you have to keep all your data in the store, which means you can't just manually call your adapter. You always have to call the store, and the store will call the adapter.

So this is an anti pattern:

const adapter = this.get('store').adapterFor('book');
return adapter.findPublishedBooks();

Because it won't push the data to the store, or serialize them.

What you instead should do is to use the query function on the store.

You can call store.query('myModel', anything) if you want a server-side filtered list. The second variable will directly be passed to the adapter.

So you would call return store.query('book', { published:true }) in your route, and then implement it in your BookAdapter with something like this:

apiManager: Ember.inject.service(),

query: function(store, type, query) {
  if(query.published) {
    let jwt = this.get('apiManager').get('jwt');

    return Ember.RSVP.resolve(
      Ember.$.ajax({
        type: "GET",
        url: this.get('apiManager').requestURL('explore'),
        dataType: 'json',
        headers: {"Authorization": "Bearer " + jwt}
      })
    );
  }
}

Also make sure you return the right data structure. ember-data expects a JSONAPI response, unless you changed that in your serializer.