Controller using the 'as' syntax fails to add new object to array

Lately, I've been experimenting with the Controller as syntax in Angular. However, I seem to be struggling to grasp its functionality. I am currently following a tutorial that utilizes $scope to bind the members of the controller function rather than using 'this' (i.e., creating var vm = this). The objective of the code is to add a newly created bookmark to an array named bookmarks within the controller. The issue arises when executing createBookmark(bookmark) and setting up Angular in index.html. Despite my efforts, I can't seem to figure out why the new bookmark is not being pushed into the bookmarks array. I even tried defining it as createBookmark(vm.bookmark), but unfortunately, this syntax is considered invalid.

Any explanations on where I might be going wrong would be extremely helpful.

MainController.js


angular
    .module('app')
    .controller('MainController', MainController);

function MainController() {
    var vm = this;

    vm.categories = [
        { 'id': 0, 'name': 'Development' },
        { 'id': 1, 'name': 'Design' },
        { 'id': 2, 'name': 'Exercise' },
        { 'id': 3, 'name': 'Humor' }
    ];

    vm.bookmarks = [
        { 'id': 0, 'title': 'AngularJS', 'url': 'http://angularjs.org', 'category': 'Development' },
        { 'id': 1, 'title': 'Egghead.io', 'url': 'http://egghead.io', 'category': 'Development' },  
    ];

    vm.currentCategory = null;

    vm.setCurrentCategory = setCurrentCategory;
    vm.isCurrentCategory = isCurrentCategory;

    vm.isCreating = false;
    vm.isEditing = false;

    vm.startCreating = startCreating;
    vm.cancelCreating = cancelCreating;
    vm.startEditing = startEditing;
    vm.cancelEditing = cancelEditing;
    vm.shouldShowCreating = shouldShowCreating;
    vm.shouldShowEditing = shouldShowEditing;

    function setCurrentCategory(category) {
        vm.currentCategory = category;
        vm.cancelCreating();
        vm.cancelEditing();
    }

    function isCurrentCategory(category) {
        return vm.currentCategory !== null && category.name === vm.currentCategory.name;
    }

    //---------------------------------------------------------------------------------------------
    // CRUD
    ---------------------------------------------------------------------------------------------

    function resetCreateForm() {
        vm.newBookmark = {
            title: "",
            url: "",
            category: vm.currentCategory
        };
    }

    function createBookmark(bookmark) {
        bookmark.id = vm.bookmarks.length;
        vm.bookmarks.push(bookmark);

        resetCreateForm();
    }

    vm.createBookmark = createBookmark;
   //---------------------------------------------------------------------------------------------
    // CREATING AND EDITING STATES
    -------------------------------------------------------------------------------------------

    function startCreating() {
        vm.isCreating = true;
        vm.isEditing = false;

        resetCreateForm();
    }

    function cancelCreating() {
        vm.isCreating = false;
    }

    function shouldShowCreating() {
        return vm.currentCategory && !vm.isEditing;
    }

index.html

<!-- Content: Bookmarks-->
        <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
            <div ng-repeat="bookmark in vm.bookmarks | filter:{category:vm.currentCategory.name}">
                <button type="button" class="close">&times;</button>
                <button type="button" ng-click="vm.startEditing()" class="btn btn-link"><span class="glyphicon glyphicon-pencil"></span>
            </button>
                <a href="{{ bookmark.url }}" target="_blank">{{ bookmark.title }}</a>
            </div>
            <hr>;

           <!-- Creating -->
            <div ng-if="vm.shouldShowCreating()">
                <button type="button" class="btn btn-link" ng-click="vm.startCreating()">
                    <span class="glyphicon glyphicon-plus"></span>
                    Create Bookmark
                </button>;

               <form class="create-form"  ng-show="vm.isCreating" role="form" ng-submit="vm.createBookmark(vm.newBookmark)" novalidate>;
                   <div class="form-group">
                       <label for="newBookmarkTitle">Bookmark Title</label>
                       <input type="text" class="form-control" id="newBookmarkTitle" ng-model="vm.newBookmark.title" placeholder="Enter title">
                   </div>;

                   <div class="form-group">
                       <label for="newBookmarkUrl">Bookmark URL</label>
                       <input type="text" class="form-control" id="newBookmarkURL" ng-model="vm.newBookmark.url" placeholder="Enter URL">
                   </div>;
                   <button type="submit" class="btn btn-info btn-lg">Create</button>;
                   <button type="button" class="btn btn-default btn-lg pull-right" ng-click="vm.cancelCreating()">Cancel</button>;
               </form>;

            </div>;
;

Answer №1

Instead of directly using the reference for vm.newBookmark in the vm.createBookmark function, it is important to clone the object first. This ensures that you are not manipulating the original object unintentionally, regardless of whether you are using controller as syntax or not.

By cloning the object before pushing it into the array, you avoid situations where the newly pushed object gets reset or duplicates get added to the array.

function createBookmark(bookmark) {
    var copiedBookmark = angular.copy(bookmark);
    copiedBookmark.id = vm.bookmarks.length;
    vm.bookmarks.push(copiedBookmark);

    resetCreateForm();
}

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 Else clause is executing twice in the jQuery code

https://jsfiddle.net/mpcbLgtt/2/ Creating a function that adds card names to an array named deck and their IDs to another array called cardIds when a div with the class "card" is clicked. The cards available are: <div class='card' id=' ...

What could be causing the issue of my database updates not reflecting until I manually refresh the

Utilizing angular with MySQL via php has been a challenge for me. Whenever I try to add something to the database, it gets added successfully, but I have to manually refresh the browser to see the updated results. I believe that angular offers great advan ...

The $injector encountered an unknown provider, cFilterProvider <- cFilter, please check your dependencies

I'm currently learning angular.js on CodeAcademy, but I've hit a roadblock with one of the exercises. Unfortunately, I keep encountering a JavaScript error that I can't seem to find a solution for even after searching online. index.html &l ...

What is the best way to store multiple arrays within an array in Python?

My goal is to create a 5x5 array in Python that will store a total of 25 arrays. Currently, I am attempting to divide an image into 25 pieces using nested loops in openCV. However, I am struggling with saving the cropped images in the slices array. board = ...

Encountering a Next.js event type issue within an arrow function

After creating my handleChange() function to handle events from my input, I encountered an error that I'm unsure how to resolve. Shown below is a screenshot of the issue: I am currently working with Next.js. In React, this type of error has not been ...

Having trouble determining the height of multiple divs on jsPDF when creating multiple pages

I am encountering a challenge while attempting to create a pdf from html divs that have varying dimensions. The code snippet provided below illustrates the process. let pages = this.rootDataContainer.nativeElement.getElementsByClassName('pdfpage&apos ...

What is the best way to output a received HTML page from the server?

I'm currently working on printing an HTML page that was generated using Node.js on my server. After sending the page to the client side as a response to an AJAX request, I have stored it in a JavaScript variable. var resp_json = printRequest.getRespo ...

Troubleshooting a 400 Bad Request Error in jQuery Ajax for WordPress Widgets

I am attempting to send information to admin-ajax.php in order to save it as a $_POST variable for handling on the cart page. However, my .ajax function keeps failing. var sendJsonA = {'value':'Data coming from JSON'} var ajaxurl = $ ...

Is there a way to conceal the parameters in the PHP GET method?

How to convert PHP GET method URL to a cleaner format? example.com/example.php?name=45 to example.com/example.php/45 Is it possible to achieve this using the .htaccess file? ...

The jQuery AJAX function appears to be unresponsive and failing to execute

I have a form that needs to update values on click of a radio button. Unfortunately, my jQuery skills are lacking. Here's what I have tried so far: HTML: <form> <input type="radio" checked="true" id="q1r1" name="q1" value="Awesome"> ...

Every item in my array is replaced by the most recently added element

Take a look at this code snippet on JSFiddle: https://jsfiddle.net/reko91/998woow6/ The issue I am facing with my project is that every time I add an element to an array, it ends up overwriting all the existing elements with the newly added one. To repli ...

Display an image fetched through the Express framework in Node.js

Utilizing the sendfile function in Node Express, I am able to serve an image from my local hard drive like so: app.get('/data/getImage/:Id', function (req, res) { console.log(req.params.Id); res.sendfile('C:\\defaultim ...

Utilize Typescript to aim for the most recent edition of EcmaScript

Are you looking to configure your typescript build to compile to the most recent version or the most current stable release of EcmaScript? For example, using this command: tsc --target <get latest version> Alternatively, in a tsconfig file: { & ...

In JavaScript, you can ensure that only either :after or :before is executed, but not both

My html slider is causing me some trouble <div class="range-handle" style="left: 188.276px;">100,000</div> Upon loading the page, I noticed that in Firebug it appears like this https://i.sstatic.net/Rgqvo.png On the actual page, it looks li ...

Retrieve JSON data from an external link and showcase it within a div, unfortunately encountering an issue with the functionality

Encountering the error message "XMLHttpRequest cannot load . No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '' is therefore not allowed access" Check out the plunker link for more information: http ...

AngularJS: encountering an undetected object due to interdependencies between services and modules

I have a module called 'maps-services' with a service named 'MapService' defined as follows: angular.module('maps-services', []) .service('MapService', [$log, function($log) { this.initMap = function() { } ...

Guide on retrieving the content type field value in Drupal and transferring it to a JavaScript file

In my custom Drupal theme, I have included a field for a SoundCloud URL with the machine name (field_soundcloud_url_). I am attempting to use a JavaScript file that will function based on the value of this variable. However, it seems to not be working as e ...

Angular JS (1.5) is experiencing difficulties with successfully processing an HTTP POST request

I've been working on implementing HTTP post requests in AngularJS (1.5). Initially, I pass the request data to a factory method, then trigger the HTTP post request and send the response back to the controller. However, I keep encountering the followi ...

Encountering an issue with npm start when attempting to launch the local host server for a React.js project

Encountering an issue with npm start Error message: 'Equipment' is not recognized as a command, operable program or batch file. internal/modules/cjs/loader.js:983 throw err; ^ Error: Module not found 'C:\Users\Home\Deskto ...

Error: null does not have the property 'renderView' to be read

My goal is to set up a main page in React.js with two buttons: Option 1 and Option 2. Clicking on Option 1 should redirect the user to the Main1 page, while clicking on Option 2 should lead them to Main2. It seems straightforward, but I am encountering the ...