Invoking a function through an array within the model where said members are declared

My goal is to consolidate all of my model functionality in one centralized location. I want the ability to access its methods from within the model itself:

JavaScript

/**
 * This application displays "OK" a specified number of times based on the button pressed
 */
angular.module('myApp', [])
.controller('MyCtrl', ['$scope', function MyCtrl($scope) {

  $scope.okModel = {
    oks: [],
    addOne: function(){
      this.oks.push(["OK"]);
    },
    addTwo: function(){
      this.addOK();
      this.addOK();
    },
    buttons: [
      {name:"addOK", action: this.addOne}, // The issue may lie here
      {name:"add2OKs", action: this.addTwo}
    ]
  };
}]);

HTML

<div ng-controller="MyCtrl">

  <!-- display the object containing all the "OK"s -->
  oks: {{okModel.oks}} 

  <!-- render the buttons -->
  <button ng-repeat="item in okModel.buttons" ng-click="item.action()">
    {{item.name}}
  </button>

  <!-- display the "OK"s -->
  <div ng-repeat="ok in okModel.oks">
    {{ok[0]}}
  </div>
</div>

While no errors are thrown, the functionality is not working as expected. The "OK"s are not being added to the model. The root of the problem seems to stem from the okModel.buttons action property.

Here's a plunker showcasing the issue: https://plnkr.co/edit/mDk43yEKSQB37QSmiKJn?p=preview

TL;DR: It appears that the problem lies with this in buttons, what alternative approach should I consider?


Extra question: Being new to Angular, I understand that I might not be utilizing models in the most effective manner. If you have suggestions for a more efficient model implementation, I would appreciate any advice.

Answer №1

To implement this in an AngularJS application the "angular" way, it is recommended to use a service to provide the model instead of defining it in the controller:

var app = angular.module('myApp', []);

app.factory('modelService', function() {
  var okModel = {
    oks: [],
  }
  okModel.addOne = function() {
    okModel.oks.push(["OK"]);
  };
  okModel.addTwo = function() {
    okModel.addOne();
    okModel.addOne();
  };
  okModel.buttons = [{
      name: "addOK",
      action: okModel.addOne
    },
    {
      name: "add2OKs",
      action: okModel.addTwo
    }
  ];

  return okModel;
});

app.controller('MyCtrl', ['$scope', 'modelService', function MyCtrl($scope, modelService) {
  $scope.okModel = modelService;
}]);

For a live example, check out this plunk.

Answer №2

It appears that @reeverd's answer is correct. Here is some additional tidying up.

  $scope.okModel = {
    oks: [],
    addOne: function(){
      oks.push(["OK"]); // Instead of pushing an array with the OK text, you can simply push the OK text itself.
    },
    addMulti: function(cnt){
      for (var ii = 0; cnt < ii; ii++) {
          // this.addOK(); It seems like the addOK function may be undefined.
          $scope.addOne(); // Calls addOne and adds OK to the oks array.
       }
    },
    buttons: [
      {name:"addOK", action: $scope.addOne}, // The issue may be with this line.
      {name:"add2OKs", action: $scope.addMulti(2)}
    ]
  };

Answer №3

The issue arises when this within the

{name:"addOK", action: this.addOne}
in the array refers to the object itself rather than the object encompassing the array. To address this, you can implement the following solution:

angular.module('myApp', [])
   .controller('MyCtrl', ['$scope', function MyCtrl($scope) {

// Define the functions that will update
// $scope.okModel.oks
var addOne = function() {
        if ($scope.okModel) {
            $scope.okModel.oks.push("OK");
        }
    },
    addTwo = function() {
        addOne();
        addOne();
    };

    $scope.okModel = {
      oks: [],
      addOne: addOne, // Assign okModel.addOne to the declared functions
      addTwo: addTwo, // Same here
      buttons: [{
          name: "addOK",
          action: addOne // Same here
      }, {
          name: "add2OKs",
          action: addTwo // Same here
      }]
    };
  }]);

Firstly, declare the functions that will alter the $scope.okModel.oks array, and then utilize these functions in both your model methods and model buttons.

UPDATE: For a functional example, refer to this plunker: https://plnkr.co/edit/sKUxjzUyVsoYp3S7zjTb?p=preview

Answer №4

Instead of simply referring to this, consider utilizing $scope.okModel instead. The context of this in a function may not always be what you anticipate, as it is determined by the method of invocation.

UPDATE:

To enhance clarity, you can extract the function definitions from okModel in the following manner:

angular.module('myApp', [])
  .controller('MyCtrl', ['$scope', function MyCtrl($scope) {

    var addOne = function() {
      $scope.okModel.oks.push(["OK"]);
    };

    var addTwo = function() {
      addOne();
      addOne();
    };

    $scope.okModel = {
      oks: [],
      addOne: addOne,
      addTwo: addTwo,
      buttons: [{
        name: "addOK",
        action: addOne
      }, {
        name: "add2OKs",
        action: addTwo
      }]
    };
  }]);

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

Unable to retrieve information from the database during the http.get request

Hey everyone, I've encountered an issue that I need help with. I'm working on retrieving data from a database using an HTTP call and then returning it to the front end. Here's what I have so far: app.get('/contentHandler/post/frontPage ...

How can I effectively save data to a session using connect-redis?

I am looking to save the username of an account into session storage. I am currently using node.js with the expressjs framework and have attempted to utilize connect-redis for storing sessions, following a tutorial on expressjs. Can someone please guide ...

Tips for saving user input from an HTML form into a database using PHP, and then transferring it to a variable in JavaScript

I've been working on a Wordpress project that involves two separate pages. The first page has a form for users to submit their name, which is then stored in a custom table in the database. After submitting the form, the user is redirected to another p ...

Convert Time: segment time devoted to the main content from the time dedicated to advertisements

Can anyone assist me with solving a math problem? Let's consider two lists or arrays: Content Array 0-50 = C1 50-100 = C2 AD Array 10-20 = A1 30-60 = A2 80-140 = A3 The desired output should be: 0-10 = C1 10-20 = A1 20-30 = C1 30-60 = A2 60-80 = C ...

Mongodb error occurred due to a duplicate key in the collection with the key value set

I need to set up multiple user accounts. The first account creation is successful, but I encounter an error when trying to create a new account: BulkWriteError: insertDocument :: caused by :: 11000 E11000 duplicate key error index: db.users.$friends. ...

Why is this text appearing twice on my screen?

When I run the code in my React app and check the console in Chrome, I notice that the response.data[0] is being printed twice. What could be causing this duplication? const fetchData = async () => { return await axios.get(URL) .then((respon ...

The model name should not be overridden if it is already being used in different fields

I have a model that I am binding on two sides. The first side is inside an html p tag, and the second side is a textarea. When I make changes to the textarea, the content inside the p tag also changes. How can I ensure that only the content in the textar ...

Tips for achieving the Bootstrap 5 Modal Fade Out effect without using jQuery or any additional plugins apart from Bootstrap

I'm facing some challenges in achieving the fade out effect in Bootstrap 5 modals. I am aiming for something similar to the "Fade In & Scale" effect demonstrated here: https://tympanus.net/Development/ModalWindowEffects/ It is crucial for me to accom ...

Is there a way to store a file in a server directory using the <a href='mypdf.pdf'> tag?

I find myself in a bit of a bind. I have a document that needs to be saved in my server directory, which is attached in an <a href='mypdf.pdf'>My pdf</a> tag. The issue is that the filename, mypdf.pdf, is dynamically changing via Jav ...

Implementing state management with Vue.js

After creating a login page and setting conditions to display different NAVBARs based on the user's login status, I encountered an issue where the rendering seemed to be delayed. In the login process, I utilized local storage to store a token for auth ...

Issues with JQuery `.click()` event

Check out this snippet of code I'm working with: $(".item").click(function () { alert("clicked!"); }); I also have (hypothetically; in reality it's more complex) the following HTML on my page: <a href="#" class="item"> ...

Executing VueJS keyup handler after the previous onclick handler has been executed

Link to example code demonstrating the issue https://codepen.io/user123/pen/example-demo I am currently facing an issue with a text field named search_val that has a watcher attached to it. The text field includes a v-on keyup attribute to detect when th ...

Having trouble with sending data from Angular to a Node.js route

I am facing an issue while trying to send the array subjectAverage to a nodejs route. I am using an express route in my angular application, but encountering 'unidentified' error when attempting to print it on the console. var app = angular.modu ...

JS | How can we make an element with style=visibility:hidden become visible?

HTML: <div id="msg-text"><p><b id="msg" name="msg" style="visibility:hidden; color:#3399ff;">This is a hidden message</b></p></div> JS: $('#url').on('change keyup paste', function() { $('# ...

AngularJS: Issue with JQuery Slider not Updating Scope Value

I am currently working on a project using AngularJS and I have integrated a jQuery slider into it. However, I am facing an issue where I need to change the value of a select box which is defined in a $scope array, but the functionality is not working as ex ...

Display pie charts on a Google Map

Utilizing a combination of JavaScript and GoogleMaps technology Within my application, there exists a screen showcasing a Google Map. In addition to this map, I have incorporated statistics detailing Population growth data displayed in the form of Pie Cha ...

Creating easy nested list views in React Native using object data structures

I am working with an array of objects that contains user data like this: const userList = [ { "firstName": "John", "lastName": "Doe", "date": "19 March 2018" }, { "firstName": "Anna", ...

When an input element is being controlled from outside the modal using a portal, it is losing focus after a key press

[Resolved] The input component is experiencing a focus issue when any key is pressed, only when its value is controlled from outside of the portal. NOTE: I apologize for any confusion. While writing this post, I identified the problem in my code, but dec ...

Arranging a JSON array based on the numerical value within an object

I am interested in sorting an array from a json file based on distances calculated using the haversine library. The purpose is to find geolocations near a specified value and display the closest results first. function map(position){ var obj, ...

Maximizing the benefits of AngularJS $routeprovider resolve functionality while maintaining a seamless loading experience for the user

After reading multiple articles on the $routeprovider resolve feature, my interest was piqued by a repository created by one of my favorite AngularJS developers, Todd Motto. You can check out his work at https://github.com/toddmotto/angularjs-styleguide#co ...