Ember.js - Handling Asynchronous Events and Callbacks

I am not utilizing Ember Data, and I have integrated an ajax call in my Model to fetch data from a remote source. Once I have successfully retrieved the data from the API, I intend to organize/filter it based on category. My approach is to handle the filtered state of the data through the controller after receiving it from the Model asynchronously.

However, I encounter an issue where the asynchronous nature of fetching data in the Model prevents me from directly calling a method in the controller to sort/filter the data for display in the template.

Below are the relevant sections of my code and a link to my jsfiddle. While iterating over the issue_list in my template allows me to display the information easily, my goal is to iterate over the categorized_issues Array. I am unsure when the issue_list array is actually set so that I can invoke the categorize method of the IssuesController.

// Default Route for /issues
App.IssuesIndexRoute = Ember.Route.extend({
    setupController: function() {
        var issues = App.Issue.all(25);
        this.controllerFor('issues').processIssues(issues);
    }
});

// Model
App.Issue = Ember.Object.extend({});
App.Issue.reopenClass({
    // Fetch all issues from the ajax endpoint. 
    // Won't work on the JS fiddle
    all: function() {                
        var issues = [];
        $.ajax({
            url: "http://localhost:3000/issues.json",
            dataType: 'json',
        }).then(function(response) {
            response.issues.forEach(function(issue) {           
                issues.addObject(App.Issue.create(issue));
            }, this);
        });

        return issues;
    },
});

// Controller
App.IssuesController = Ember.ArrayController.extend({
    issue_list: [],
    categorized_issues : {"open":[], "closed": []},

    processIssues: function(issues) {
        this.set('issue_list', issues);
        return issues;
    },

    categorize: function() {
        var self = this;
        this.issue_list.forEach(function(i) {
            // Based on the issue open or closed status
            if (i.status == "open") {
                self.categorized_issues["open"].addObject(i);
            } else {
                self.categorized_issues["closed"].addObject(i);
            }
        });
    },
});

My strategy is as follows:

  1. Retrieve Data from Model
  2. Reorganize the data based on its status (open or closed) in the controller
  3. Present this modified data in the template

However, I am facing difficulties in implementing this. Any suggestions on how to proceed?

DEBUG: ------------------------------- 
DEBUG: Ember.VERSION : 1.0.0-rc.2
DEBUG: Handlebars.VERSION : 1.0.0-rc.3
DEBUG: jQuery.VERSION : 1.9.1
DEBUG: ------------------------------- 

Answer №1

To improve the efficiency of the code, a simple solution would be to make the declaration of categorize() as an observer:

App.TasksController = Ember.ArrayController.extend({
    task_list: [],
    categorized_tasks: {"pending":[], "completed": []},

    processTasks: function(tasks) {
        this.set('task_list', tasks);
        return tasks;
    },

    categorize: function() {
        var self = this;
        // Clear the arrays to prevent duplicate objects
        self.get("categorized_tasks.pending").clear();
        self.get("categorized_tasks.completed").clear();

        this.task_list.forEach(function(t) {
            // Categorize tasks based on their status
            if (t.status == "pending") {
                self.get("categorized_tasks.pending").addObject(t);
            } else {
                self.get("categorized_tasks.completed").addObject(t);
            }
        });
    }.observes("task_list.@each"),
});

By setting the observer to trigger on each array change, we ensure efficient monitoring. Using Ember.run.once would further optimize the process:

App.TasksController = Ember.ArrayController.extend({
    task_list: [],
    categorized_tasks: {"pending":[], "completed": []},

    processTasks: function(tasks) {
        this.set('task_list', tasks);
        return tasks;
    },
    taskListObserver : function(){
        Ember.run.once(this, this.categorize);
    }.observes('task_list.@each'),

    categorize: function() {
        var self = this;
        // Clear the arrays to prevent duplicate objects
        self.get("categorized_tasks.pending").clear();
        self.get("categorized_tasks.completed").clear();

        this.task_list.forEach(function(t) {
            // Categorize tasks based on their status
            if (t.status == "pending") {
                self.get("categorized_tasks.pending").addObject(t);
            } else {
                self.get("categorized_tasks.completed").addObject(t);
            }
        });
    }
});

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

Is it possible for images underneath to receive focus when hovering over them?

I'm struggling with a layout of thumbnails on my page. We'll refer to them as A, B, C, etc. They are currently displayed like this: A, B, C, D, E, F, G, H, I, J, K, L, M, N... and so on. When you hover over one thumbnail, it enlarges by 2.5 t ...

Having trouble with jQuery UI draggable when using jQueryUI version 1.12.1?

Currently, I am diving into the world of jQuery UI. However, I am facing an issue with dragging the boxes that I have created using a combination of HTML and CSS. My setup includes HTML5 and CSS3 alongside jQuery version 1.12.1. Any suggestions or help wou ...

The server's delayed response caused the jQuery ajax request to be aborted

Encountering delayed AJAX response from the PHP server upon aborting the AJAX request. Currently utilizing the CodeIgniter framework for the server script. Javascript Code: cblcurrentRequest = $.ajax({ url: baseurl + 'Login/getChannelBra ...

When NextJS calls a dynamic page in production, it redirects to the root page

My Desired Outcome When a user inputs https://www.example.com/test, I want them to receive the content of the NextJS dynamic route /test/index.js. This functionality is successful in my local environment. The Current Issue Despite a user entering https:/ ...

Generate a graph by utilizing $getJSON and ChartJS

I am currently working on creating a bar chart using ChartJS and a JSON file. The data format is provided below, with each object containing information about the station name and arrival time. My goal is to populate an array where the x-axis represents St ...

Ways to effectively handle diverse Angular module dependencies

Although I am still new to Angular, I have been striving to write more modular code and rely less on cramming logic into the controller. Instead, I have been utilizing independent services. However, a recurring issue I am facing is having to re-declare the ...

Tips for concealing scrollbars across various browsers without compromising functionality

Is there a way to hide the scrollbar functionality on a horizontal scrollbar without using "overflow: hidden"? I need to maintain JS functionality and ensure compatibility with all modern browsers. $j = jQuery.noConflict(); var $panels = $j('#primar ...

Angular: Radio button groups are not responding correctly when populated within a loop using ng-repeat

My goal is to populate multiple sets of radio buttons in a loop by combining the group name and index to ensure each set is uniquely grouped. However, I am facing an issue where only the last group in the loop has a checked radio button, while all other gr ...

Transmitting special symbols through Socket.io

I've been working on a small project based on Socketio 0.9 and everything is running smoothly, except for a minor problem with special characters. In the web client, I am creating a dynamic JSON object using JavaScript that is then emitted to the ser ...

Utilize clipboard functionality in automated tests while using Selenium WebDriver in conjunction with JavaScript

How can I allow clipboard permission popups in automated tests using Selenium web driver, Javascript, and grunt? https://i.stack.imgur.com/rvIag.png The --enable-clipboard and --enable-clipboard-features arguments in the code below do not seem to have an ...

Guide to transferring req.params to a callback function within node.js

I am currently working on a Node.js project using Express. I have been attempting to retrieve data using the NPM request package, utilizing a specific URL and passing an anonymous callback function to handle the resulting JSON file. The code below has bee ...

Issues with non-functional plugins that utilize AJAX functionality

I am encountering an issue with my code that includes an ajax script for deleting a record, along with an animation during the deletion process. However, when I try to integrate the ajax script with plugins for confirmation, it seems to not be working prop ...

Implementing Material-UI’s FlatButton and Dialog in ReactJS for dynamic TableRow functionality

I am working with Material-UI and have implemented a <Table> component. Each dynamically rendered <TableRow> in the <TableBody> needs to include a button (<FlatButton>) within one of the columns. When this button is clicked, a <D ...

Retrieve various key-value pairs from the JSON data in the global market API using AJAX

I have recently developed a real-time API specifically designed for monitoring World Stock Markets. This API covers popular indices such as Nifty, Dow Jones, Nasdaq, and SGX Nifty. If you are interested in accessing this Real Time API, you can do so by vi ...

Creating an uncomplicated search bar that dynamically adjusts values based on its function

Summing it up, there is a div situated within my app.component.html: <div class="col-lg-6 search-div"> <div class="input-group"> <input type="text" class="form-control" placeholder="Search for..."> <span class="input-group-b ...

Show the current time using Moment.js

I am currently working on developing a clock component that displays the current time in real-time. Issue: The initial time is correctly displayed when the page loads (HH:mm A), but the clock does not update dynamically. clock.component.ts : import { ...

Manipulating the length of an array based on a specified range using Vue.js

I'm currently working on a client's range filtering feature using Vue.js. The filter involves an input element with the type range to adjust the total number of clients displayed. I have successfully linked the value of the input to the **clients ...

Set a variable equal to the output of an external function, but receive an undefined value in

I've been facing an issue where I'm trying to store the value of an external function in a JavaScript variable, but it keeps returning undefined. The external function in question is designed to search for a specific record within a database: f ...

The compare function in bcryptjs will result in a false output if the passwords include numerical

I have successfully used bcryptjs to hash my passwords during user registration. However, I am facing an issue with the bcrypt.compare function when attempting to log in. The function returns a false promise when passwords contain numbers or special charac ...

Encountering an 'Uncaught TypeError' with Tumblr API due to undefined property 'type' not being read

I have multiple feeds on my website, each fetching posts from various tags. The first feed is functioning properly, but the 2nd and 3rd feeds are displaying the following error: Uncaught TypeError: Cannot read property 'type' of undefined All ...