How can we leverage jQuery deferred within Backbone Marionette composite views, where each items view contains a form, to execute a task after each form submission is successful?

I am utilizing a Backbone Marionette composite view in which each child item view contains its own form.

var DependentsFormFields = Backbone.Marionette.CompositeView.extend({
    template: 'dependents_form_fields_wrapper',
    itemViewContainer: '#dependents',
    itemView: DependentsFormFields,
    events: {
        "click #save-dependent-section" : "saveSection"
    },
    saveSection: function(event) {
        event.preventDefault();

        this.children.each(function(childView){
            childView.submitForm();
        });
    }
});

var DependentsFormFields = Backbone.Marionette.ItemView.extend({
    template: 'dependent_form',
    submitForm: function() {
        var _this = this;

        var data = Backbone.Syphon.serialize(_this);

        _this.model.save(data, {
            url: _this.model.urlRoot,
            success: function() {
                App.Components.Form.ErrorHandler.removeErrors({
                    view: _this
                });
            },
            error: function(model, response) {
                App.Components.Form.ErrorHandler.applyErrors({
                    view: _this,
                    errorData: JSON.parse(response.responseText)
                });
            }
        });
    }
});

All of the above functions as intended. However, a new requirement has surfaced that demands a recalculation of an 'amount due' after the Dependent section has been saved. In another part of the codebase, I have handled this with

App.execute("recalculate:amount:due");

I am currently facing difficulties in comprehending how to utilize jQuery's deferred (or promises or when...) to wrap the this.children.each process within the saveSection function of the composite view. The objective is to trigger the command only after all child sections have been successfully saved.

Answer №1

Here are some steps you can follow.

To begin with, ensure that your submitForm function returns a deferred object:

submitForm: function() {
    // variable declarations

    return _this.model.save(data, {
        // code remains the same
    });
}

Next, keep track of each deferred object and calculate the total amount due upon their completion.

saveSection: function(event) {
    event.preventDefault();

    var deferreds = [];
    this.children.each(function(childView){
        deferreds.push(childView.submitForm());
    });

    $.when.apply($, deferreds).done(function(){
      // perform calculations for amount due
    });
}

If you are unsure about how deferred objects work, you may find it helpful to read two blog posts I wrote on the topic:

Answer №2

The approach I ultimately took:

Upon conducting extensive research and experimentation, it became apparent that backbone models do not inherently adhere to the deferred pattern. While it is possible to leverage promises in the ajax calls that backbone sync defers to, this method proved to be unreliable.

To address this issue, I opted to incorporate the Backbone Deferred plugin into my project.

var Person = Backbone.Deferred.Model.extend({
    urlRoot: App.apiRoot + '/Person'
});

var People = Backbone.Collection.extend({
    model: Enrollment.Person
});

var DependentsFormFields = Backbone.Marionette.CompositeView.extend({
    template: 'dependents_form_fields_wrapper',
    itemViewContainer: '#dependents',
    itemView: DependentsFormFields,
    events: {
        "click #save-dependent-section" : "saveSection"
    },
    saveSection: function(event) {
        event.preventDefault();

        this.children.each(function(childView){
            childView.submitForm();
        });

        var promises = [];
        this.children.each(function(view){
            promises.push( view.submitForm() );
        });

        $.when.apply($, promises).done(function() {
            App.execute("recalculate:enrollment:subscription:rate");
        });

    }
});

var DependentsFormFields = Backbone.Marionette.ItemView.extend({
    template: 'dependent_form',
    submitForm: function() {
        var _this = this;

        var data = Backbone.Syphon.serialize(_this);

        return _this.model.save(data, {
            url: _this.model.urlRoot,
            success: function() {
                App.Components.Form.ErrorHandler.removeErrors({
                    view: _this
                });
            },
            error: function(model, response) {
                App.Components.Form.ErrorHandler.applyErrors({
                    view: _this,
                    errorData: JSON.parse(response.responseText)
                });
            }
        });
    }
});

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

Encountering an 'undefined' property error when clicking a button in Angular 1.x

Hey there, I have a question that might seem simple to some of you. I'm struggling with fixing an error and I don't quite understand why it's happening :( This error popped up while using Angular 1.x. What I need help with is creating an al ...

Can we tap into the algorithm of curveMonotoneX in d3-shape?

I'm currently using curveMonotoneX to draw a line in d3 import React from 'react'; import { line, curveMonotoneX } from 'd3-shape'; export default function GradientLine(props) { const { points } = props; const lineGenerator ...

Upcoming construction: Issue encountered - The Babel loader in Next.js is unable to process .mjs or .cjs configuration files

Within my package.json file, I have set "type": "module" and "next": "^12.2.5". In my tsconfig.json: { "compilerOptions": { "target": "ES2022", "module": "esnext ...

Optimizing performance: Making the most of mongoose updateMany middleware

PROBLEM SOLVED: SOLUTION PROVIDED BELOW I have a piece of code where I am updating elements one by one: //registerCustomers.js const CustomerRegistrationCode = require("../models/CustomerRegistrationCode"); const setRegCodesToUsed = async (regC ...

Creating a list of font sizes for each <p> tag in my HTML document

I am looking to create an array containing the font sizes of all the p tags in my HTML document. How can I specifically target only the p elements and not their parent elements? ...

Issue: mongoose.model is not a valid function

I've been diving into several MEAN tutorials, and I've hit a snag that none of them seem to address. I keep encountering this error message: Uncaught TypeError: mongoose.model is not a function Even after removing node_modules and reinstalling ...

JavaScript : Retrieve attributes from a JSON object

Situation : I have a JSON object with multiple properties and need to send only selected properties as a JSON string to the server. Approach : To exclude certain properties from the JSON string, I utilized the Object.defineProperty() method to set enumera ...

Iterating through a JSON query in AngularJS using the ng-repeat directive

Using AngularJS in my current project has been a smooth experience so far. One thing I have noticed is that when I loop over employees in my view, I have to use the code <li ng-repeat="employee in employees.employee"> instead of just <li ng-re ...

Adjusting the navigation image as it passes through various div elements during scrolling

Is it possible to dynamically change an image in the navigation bar based on the user's scroll position? For example, I want pic1 to be displayed when the page content is at the top, then switch to pic2 once the user reaches the footer, and then back ...

The request in Node.js was terminated

While using express and body-parser to transfer a large amount of data from one server to another, I encountered the following exception after some time: { "message": "request aborted", "code": "ECONNABORTED", "expected": 99010, "length": ...

Troubleshooting the issue of CSS animations activating twice and causing a flickering effect specifically in the Firefox browser

I am facing an issue with CSS animations in Firefox. When I try to slide in some radio buttons upon clicking a button, the animation seems to be firing twice in Firefox while it works fine in Chrome. I have attempted several solutions but haven't been ...

Ways to pass JavaScript variables to a Python script

Hey there! I'm currently facing an issue with retrieving variables from JS to use in my python code. Despite trying methods like AJAX and JQuery, I haven't had much success yet. It's possible that I'm missing something crucial in the pr ...

The Google Docs viewer is displaying an empty screen

I have been utilizing the Google Docs viewer on my website: <div class="embed-r embed-responsive-a"> <iframe class="embed-responsive-it" src="https://docs.google.com/viewer?embedded=true&amp;url=http://LINK.PDF"></iframe> </div& ...

The JavaScript animations in AngularJS using ng-class are not being activated

I've been attempting to apply js-defined animations to the ng-class directive using the standard syntax of add and remove, but for some reason, the animations are not running. After checking the logs, it seems that the add and remove functions are not ...

Deciphering Google location data using JavaScript

It appears that this code is not functioning properly for unknown reasons let url = "https://maps.googleapis.com/maps/api/place/search/json?"; url += "location="+lat+","+lng+"&"; url += "radius=500&"; url += "types=&"; url += "name=&"; url ...

Incorporating Angular module into the mean.io bundle

Need help with adding the angular-ui-grid module to a mean.io package: $ cd packages/custom/mypackage $ npm install angular-ui-grid --save To import the JS, add this line to packages/custom/mypackage/public/index.js: import 'angular-ui-grid'; ...

Executing Two Distinct JQuery Api Requests

I'm facing a challenge with integrating the data from two different API calls and processing them together. After receiving JSON responses from both calls, I convert them into GeoJSON format. The next step is to combine these geojson objects in anothe ...

What is the procedure for iterating through the square brackets of a JSON array?

Here's the data I have: $json_data_array = '[ { "id": 1, "value": "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="bfd7cdffcbdacccb91dcd0d2">[email protected]</a>", ...

Guide on extracting unique identifiers from an array of objects and sorting them by the earliest date in JavaScript

I've got an array of objects and I'm looking to retrieve the items with unique IDs while also selecting the earliest date. For example: [{id:1, date: Jan 12}, {id:2, date: Feb 8}, {id:3, date: Feb 8}] var array = [{id: 1, date: Jan 12 2021 08:00 ...

To prevent flickering when using child flex elements, it's best to use position fixed along with a dynamically updated scrollbar position using Javascript

My navigation component includes a slim banner that should hide upon scroll and a main-nav bar that should stick to the top of the screen and shrink when it does so. I initially looked into using Intersection Observer based on a popular answer found here: ...