The Bookshelf JavaScript model is creating a never-ending cycle of saving and changing data

In the Bookshelf model provided below, the users password is hashed when the model is saved. However, an issue arises when changing the model.set() call to a model.save(), leading to an endless loop of saving and changing.

var User = bookshelf.Model.extend({
    tableName: 'users',
    hasTimestamps: true,

    constructor: function() {
        var self = this;
        bookshelf.Model.apply(this, arguments);

        this.on('saving', function(model) {
            if(!model.get('password')) {
                return self.hashPassword(model);
            }
        });
    },

    hashPassword: function(model) {
        bcrypt.genSalt(10, function(error, salt) {
            bcrypt.hash(model.attributes.password, salt, function(error, hash) {
                model.set({password: hash});
                console.log(model.attributes);
            });
        });
    }
});

It is known that Backbone offers a silent: true option to avoid triggering a change event with save(), but it is unclear whether or not Bookshelf supports this feature.

What are some ways to save the changes made by model.set() without encountering a save/changed loop?

Answer №1

After doing some investigation, it appears that the issue lies in the model saving before the hash_password method has completed its execution. To address this, I implemented a promise for the bcrypt code as shown below:

hashPassword: function(password) {
    return new Promise(function(resolve, reject) {
        bcrypt.genSalt(10, function(error, salt) {
            if(error) return reject(error);

            bcrypt.hash(password, salt, function(error, hash) {
                if(error) return reject(error);
                return resolve(hash);
            });
        });
    });
}

I also made significant changes to the model's constructor to incorporate this updated approach:

constructor: function() {
    var self = this;
    bookshelf.Model.apply(this, arguments);

    this.on('saving', function(model) {
        if(!model.attributes.password) {
            delete model.attributes.password;
        } else {
            return self.hashPassword(model.attributes.password)
            .then(function(hash) {
                model.set({ password: hash });
            });
        }
    });
}

Hopefully, this solution proves helpful to someone :-)

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

I require a platform that can effectively store, retain, and provide access to information across various interfaces

Although it may seem like a basic issue, as someone new to Angular, I'm facing a problem. I have 2 views that both require access to the same user input data from a form. Each view has its own controller. Here's the current situation: JAVASCRIP ...

What is the best way to clear a MongoDB objectId field, set it to null, or ultimately remove it from a

Custom Modal Schema : { "title":{type:String,required:true}, "genre":{type:mongoose.Schema.Types.ObjectId,ref:"Genre"} } Upon creating a document using this schema, the document structure appears as follows: { "_id":ObjectId("5abcde12345fgh6789ijk ...

Transform an Array by replacing a specific value or creating a new one

Dealing with two arrays, both potentially of large lengths: The goal is to update the status in Array 1 with the corresponding status from Array 2. Here's a sample output: [{ value: 123, status: 'demo', type: '...' }, {value: 233 ...

Step-by-step guide on incorporating a dynamic radio button into a dynamically generated table using jQuery

I need help adding a radio button to my dynamically created table using the following HTML code: <div class="row container"> <div class=" col m12 l6 s12" style="height:200px; overflow:scroll;"> <table id="staff"> < ...

Adjust image source based on media query (CSS or JavaScript)

Is there a way to update the image src based on a media query with a maximum width of 515px? I'm considering using JavaScript, jQuery, or even AngularJS if there is an event equivalent to a CSS media query that can achieve this. I want to have differ ...

How can you access the input value from load dash's debounce function in a Vue.js application?

Is there a way to capture the input entered during the @typing event of the b-autocomplete component in Buefy? During the @typing event, the debounce method is called with specific parameters as shown below- <b-field label="Location"> ...

How to transfer a parameter to a JavaScript function within an Ajax success callback?

While attempting to call the UpdateItem function using AJAX with an anchor tag, I encountered a console error. Error : req is undefined function updateItem(id, desc, vehicleno){ alert("i am here"); $('#ProcessModal').modal(&a ...

Issues with browser tab icon disappearing upon being pushed to Github for a Vue project

I'm facing an issue where my browser tab icon is not showing up after I push my repository to GitHub. Interestingly, it shows up perfectly fine when I test it on localhost. On the left is my website hosted on GitHub, while on the right is my website ...

What is the best way to split a JSON array into two separate JSON arrays?

Greetings, I have received a JSON response. response.data: [{ "id": 1, "datefrom": "2018-08-30 11:21:25", "dateto": "2018-08-31 11:21:25", }, { "id": 2, "datefrom": "2018-08-30 11:21:25", "dateto": " ...

EJS installation issue

I am attempting to add ejs to my project for the first time and I am running into some difficulties. I have tried several commands but none of them are successful. Some of the commands I have attempted are provided below : npm i ejs npm i ejs --save npm i ...

Tips for extracting innerHTML or sub-string from all elements that have a specific class name using JavaScript

When it comes to shortening the innerHTML of an element by its Id, I have found success using either slice or substring. While I'm not entirely clear on the differences between the two methods, both accomplish what I need them to do. The code snippet ...

Exploring JSON data with multiple nested layers of iteration

I'm currently working on a project that involves parsing through a JSON file with a complex structure. I've been attempting to extract a link to an image within the JSON data, but my current approach is resulting in an error. Below you'll fi ...

What is the best way to find matching pairs of delimiters in a JavaScript regex pattern

It seems like this problem would be impossible; I thought that Javascript's regex flavor did not have recursive interpolation or the .NET balancing groups feature. However, on regex.alf.nu, problem 12 is to match balanced pairs of < and >. Unles ...

The HttpContext.Current State being lost due to PageMethods call in JavaScript

I find myself in a bit of a pickle. I've been utilizing JavaScript's PageMethod feature and it's been working wonderfully. However, I'm running into an issue when trying to access the HttpContext's state, which is returning a value ...

The issue of a shallow link malfunctioning when used in connection with middleware at the root

Issue: I'm facing a problem with the shallow option in middleware located at ./src/middleware.ts. Although the link in the browser is changing, the pages are not updating accordingly. I have used NextLink component in the sidebar for navigation, as ...

Error: No schema found for the specified "User" model

Attempting to establish a connection with the MongoDB database using Mongoose and defining the model resulted in the following error message: MissingSchemaError: Schema hasn't been registered for model "User" Several approaches were taken to address ...

Even in the absence of the element on the page, the VueJS instance is still being invoked

I am encountering an issue where all my VueJS instances are being executed, even if the element associated with them is not present on the page. Currently, I have defined a mixin as follows: var mixin = { methods: { listEvents(parameters) { ...

Converting JSON data into an array containing individual objects, and inserting a new item into each object

I've been working on retrieving data from a JSON file and successfully creating an array of objects. However, I am trying to add an item to each object in the array simultaneously. Check out my current code: var linklist = []; $.getJSON('links. ...

What is the best way to manage executing functions on data that could potentially be undefined?

When working with React, I often encounter the need to write functions that rely on a component's state. One common issue I face is the necessity to check if a piece of state is defined before proceeding with any actions. For instance, I have a funct ...

Is there a method in bootstrap that reveals the elements with the hidden class?

Currently, I am loading data into a bootstrap table on my JSP. The table class is hidden at the moment. After successfully uploading the data into the bootstrap table, I have implemented the following code: $(function() { var table = $('#Table') ...