Ember 2: Display a loading message only if the IDs were part of the initial response

I frequently use the following code snippet in my projects:

{{#each model.posts as |post|}}

  <div>post.title</div>

{{else}}

  <div>Loading the posts...</div>

{{/each}}

However, I sometimes face uncertainty regarding whether the model.posts array is empty or not.

How can I display a message instead of endlessly loading an empty array?

The issue arises on the /category/2 page, specifically within the category.hbs template where the posts are "sideloaded" in the response structure, like so:

{
  "data": {
    "id": "1",
    "type": "categories",
    "attributes": {
      "name": "Books"
    },
    "relationships": {
      "posts": {
        "data": [{
          "id": "14",
          "type": "posts"
        }, {
          "id": "15",
          "type": "posts"
        }, {
          "id": "20",
          "type": "posts"
        }]
      }
    }
  },
  "included": [{
    "id": "14",
    "type": "posts",
    "attributes": {
      "commented": true,
      "comments": 10
    }
  }, {
    "id": "15",
    "type": "posts",
    "attributes": {
      "commented": false,
      "comments": 10
    }
  }, {
    "id": "20",
    "type": "posts",
    "attributes": {
      "commented": false,
      "comments": 10
    }
  }]
}

I am utilizing ember-data and defining the following models:

category

name: DS.attr('string'),
posts: DS.hasMany('post')

post

commented: DS.attr('string'),
comments: DS.attr('number'),
category: DS.belongsTo('category')

I may consider creating an ember-twiddle to better demonstrate my issue with ember-data...

Answer №1

Understanding the Use of 'Links'

Based on the feedback provided, it seems there is some confusion regarding how links operate. The concept itself is quite straightforward. Your payload for the category should adhere to the following structure:

{
  "data": {
    "id": "1",
    "type": "categories",
    "attributes": {
      "name": "Books"
    },
    "relationships": {
      "posts": {
        "links": {
          "related": "/posts?category_id=2"
        }
      }
    }
  }
}

Ember Data will automatically recognize this setup so that when you access the computed property model.posts, it will trigger a request to /posts?category_id=2.

Handling Asynchronous Loading

If you are loading the category and its associated posts in the model() hook of your route, the promise will already be resolved by the time the template is rendered. Therefore, the current implementation of displaying Loading the posts... will only appear if the category has no posts, not while it's still loading. In its present form, it serves little purpose.

To display a loading animation, consider loading the category within a computed property on the controller instead of the model() hook. You can achieve this with code similar to the following:

export default Ember.Controller.extend({
  ...
  category: Ember.computed(
    function() {
      return this.store.query('category', {...});
    }
  ),
  ...
});

You can then check the status of the promise in your template. While we developed an Ember addon called ember-promise-block, I recommend using ember-deferred-content as it receives more frequent updates and offers greater flexibility.

Your template will subsequently resemble the following structure:

{{#deferred-content category as |d|}}
  {{#d.fulfilled}}
    <div>post.title</div>
  {{/d.fulfilled}}

  {{#d.pending}}
    <div>Loading the posts...</div>
  {{/d.pending}}
{{/deferred-content}}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The React component fails to inherit any props that are passed to it when it is rendered using a logical operator

I'm facing an issue with a component that doesn't seem to receive any props when I use a logical operator in conjunction with it. Oddly enough, if I render the component without the conditional statement, everything works fine. But as soon as I a ...

What is the best way to increase a numerical input?

While experimenting with HTML input elements, I decided to utilize the step attribute. This allowed me to increment the current value by 100 when clicking the up or down arrows in the input field. However, I discovered that the step attribute restricts th ...

What causes the variation in output when utilizing React's setState() function?

I'm puzzled by this Whenever I try this.setState({count: count+1}), it only updates the count once no matter how many times I click But when I attempt this.setState({count: this.setState.count}), every click successfully updates the cou ...

Exploring the concept of JavaScript closures and the pitfalls of name clobber

Is it possible for variables defined inside an inner function with the same name as a variable in an outer function to be isolated from the outer variable? function() { var myTest = "hi there"; ( function( myLocalTest ) { myLocalTest = "go ...

switchMap: Triggering multiple requests simultaneously (2)

Currently, I am utilizing Angular 2 RC-4 and facing an issue where a network request is being triggered twice whenever there is a change in the input box. This is what my code looks like: component.ts this.term = new Control(); this.suggestions = this. ...

Exploring the functionality of the JavaScript Date constructor in relation to

Will using new Date('2015-01-01') provide me with the exact moment equivalent to 2015-01-01T00:00:00Z? ...

When you click on `window.open('my-app://', '_blank');`, it won't directly open the desktop app from the browser. However, typing `my-app://`

When I open Chrome and enter my-app:// in the URL or search bar, a dialog box pops up saying "Open my-app? A website wants to open this application". Clicking ok opens my Electron app. I'm looking to add similar functionality to my React app, where t ...

What is the reason that accessing array elements with negative indices is significantly slower compared to accessing elements with

Let's explore a JavaScript performance test: const iterations = new Array(10 ** 7); var x = 0; var i = iterations.length + 1; console.time('negative'); while (--i) { x += iterations[-i]; } console.timeEnd('negative'); var y = ...

Tips on preventing duplication of APIs when retrieving data using nextjs

In my code, I have a function that can be called either from server-side rendering or client side: export const getData = async (): Promise<any> => { const response = await fetch(`/data`, { method: 'GET', headers: CONTENT_TYPE_ ...

Event that signifies a change in the global state of the Angular 2 router

Is there a universal event that can be utilized for state change/start across all components, similar to the Component Lifecycle Hooks ? For example, in UI-router: $rootScope.$on("$stateChangeStart", function() {}) ...

Tips for avoiding problems with quoting and using apostrophes in a JavaScript function inside a tag in a JSP file

Within my JSP, I have a string value stored in ${state.status.code} that I need to pass to a JavaScript function when a table element is clicked using onClick to trigger the showStatus function. Here is how I have attempted to achieve this: <c:set var= ...

Fixing the issue with animated scrolling in React Native's Flatlist component

I attempted to customize the default refresh indicator for a Flatlist in React Native. My goal was to create something similar to Snapchat, Instagram, or the default iOS refresh indicator instead of the unattractive Android indicator. This is what I tried: ...

ReactJS is encountering a situation where two children are using the same key and causing

When I try to view the profile information of another user, I encounter a duplicate key error that says: "Warning: Encountered two children with the same key, ``. Keys should be unique so that components maintain their identity across updates. Non-unique k ...

How to dynamically insert elements into the HTML page using Angular

When my page first loads, it looks like this <body> <div class="col-md-12" id="dataPanes"> <div class="row dataPane"> Chunk of html elements </div> </div> <div class"col-md-12 text-right"> <input type="butt ...

The elusive cookie in NodeJS remained just out of reach

After setting a cookie using the code below: router.get("/addCartToCookie", function(req, res) { let options = { maxAge: 1000 * 60 * 15, httpOnly: true, }; let cartData = { name: "test cookie", slug: slugify(&quo ...

Is it possible to use AngularJS promises without callbacks?

Typically, when I want to retrieve data asynchronously, I would use the following approach: var promise = $http.get('/api/v1/movies/avengers'); promise.then( function(payload) { $scope.movieContent = payload; }); This scenario is quite ...

Send an array to a function with specified criteria

My current code successfully splits an array, but I need to pass a value when the array condition is met. For example, here is how the value is split into an array: var myArr = val.split(/(\s+)/); If the array in position 2 is empty, I need to use ...

Vue.js navigation guards, restrict access to all unauthorized routes, grant entry to specific routes upon successful authentication

I'm currently working on implementing a navigation guard in Vue.js with a specific logic: I want to restrict access to all routes that require authentication and redirect users to the login page if they are not authenticated. The only exception is the ...

Check for my variable in the redux state before proceeding

Currently, I am creating connection and registration screens, with a profile button on the bottom tab bar. The objective is for the user to be directed to their profile page if they are logged in (user data stored in Redux), or to a landing screen with log ...

Determine the success of an SQL query in Node.js

I've created a basic API using nodejs to connect my Flutter app with a SQL Server database, but I have a question. How can I verify if the query was successful in order to return different results? I'm attempting an update after a successful in ...