Angular - My view has an element that is connected to a variable in a service, yet the view fails to reflect any updates made to the service

I have a variable called appList that is stored in a service and initialized as [1, 2, 3]. In my controller, I import appList and bind it to the view in a list. There is a function called modifyAppList in the controller that invokes a similar function in the service when a button in the view is clicked. Surprisingly, although the value in the service changes (as confirmed by console logs), the view does not update accordingly. If someone could review the code and provide an explanation for this behavior, I would greatly appreciate it.

NOTE: Changing the contents of modifyAppList() to

appList[0] = 5; appList[1]= 6; appList[2]=7;
will produce the expected result. However, there seems to be some issue with assigning appList to a new array within modifyAppList().

angular.module('app', []);

angular.module('app')
.factory('appService', appService)

function appService(){
var appList = [1,2,3];
var modifyList = [5,6,7];
var modifyAppList = function(){
console.log("At the beginning of modifyAppList: ", appList)
appList = [];
console.log("After appList=[] : ", appList)
for(var i = 0; i < 3; i++){
appList.push(modifyList[i]);
}
console.log("After modification: ", appList)


}
return {
getAppList : function(){
return appList;
},
modifyAppList : modifyAppList
}
}

angular
.module('app')
.controller('appCtrl', appCtrl)

appCtrl.$inject = ['appService'];
function appCtrl(appService){

this.appList = appService.getAppList();
this.modifyAppList = function(){
appService.modifyAppList();
var testList = appService.getAppList();
console.log("After modification, and calling getList() : ", testList)
}
}
<body ng-controller="appCtrl as vm">

 <ul>
    <li ng-repeat="num in vm.appList" ng-bind="num"></li>
  </ul><br>
  <button ng-click="vm.modifyAppList()">modifyAppList()</button>


  <script src="controller.js"></script> 
  <script src="service.js"></script>
  

</body>

Answer №1

When the code executed appList = []; in the service, it essentially created a new object reference for the array. However, the original object reference in the controller still pointed to the old array. (appList = []; is equivalent to appList = new Array();)

To preserve the original reference, you should utilize angular.copy:

function appService(){
    var appList = [1,2,3];
    var modifyList = [5,6,7];
    var modifyAppList = function(){ 
        angular.copy(modifyList, appList);
    }
    return {
        getAppList : function(){
            return appList;
        },
        modifyAppList : modifyAppList
    }
}

As stated in the AngularJS Docs:

angular.copy

Usage

angular.copy(source, [destination]);

This function creates a deep copy of the source, which could be an object or an array.

  • If a destination is specified, all its elements (for arrays) or properties (for objects) are removed and then replaced with the elements/properties from the source.

--AngularJS angular.copy API Reference

Rather than completely replacing the array with a new one, angular.copy updates the contents of the array. This ensures that changes made by the service reflect in the controller and vice versa.

Answer №2

Hey there, the service is currently being updated and you have not assigned the value yet. Please make sure to check the link provided.

JS

app.controller('MainCtrl', function($scope , appService) {
  $scope.name = 'World';

        $scope.appList = appService.getAppList();
        $scope.modifyAppList = function(){
            console.log("After modification: ")
            appService.modifyAppList();
            var testList = appService.getAppList();
            $scope.appList = appService.getAppList();
            console.log("After modification, and calling getList() : ", testList)
        }
});

for reference https://plnkr.co/edit/XRAEwtiV9vdv0beiS5yU?p=preview

https://i.sstatic.net/ml0bh.png

Answer №3

Why not simplify things? Just make sure that your updateList function in the appService module returns the updated list.


  var updateList = function() {
    console.log("Initial list: ", list);
    list = [];
    console.log("After emptying list: ", list);
    
    for (var i = 0; i < 3; i++) {
      list.push(updatedItems[i]);
    }

    console.log("After updating: ", list);

    return list;
  }

Then, in your Controller:


this.updateList = function(){
  this.list = appService.updateList();
}

Answer №4

appService.retrieveAppList();

Simply calling the function is not sufficient. You need to assign it to the controller's scope:

this.appList = appService.retrieveAppList();

It is important to note that the variable appList within your service is separate from the one in the controller.

--update--

The issue lies within this line of code in the service:

appList = [];

While you initially assign appList to this.appList in the controller, when modifyAppList is called again, a new empty array is assigned to it, breaking the connection with the previous data.

To resolve this, remove the line:

appList = [];

and update the following line to:

appList[i] = modifyList[i];

This adjustment will ensure that the changes are made within the existing reference, producing the desired outcome.

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

Analyzing DynamoDB Query

I am on a mission to recursively analyze a DynamoDB request made using the dynamo.getItem method. However, it seems that I am unable to locate a similar method in the DynamoDB SDK for Node.js. You can find more information about DynamoDB SDK at http://do ...

Is it necessary to use a while loop instead of a for loop when iterating through and removing values from a JavaScript array?

const array = [1, 2, 3, 4, 5, 6, 7, 8, 9]; function checkOdd(value) { return value % 2; } for (let i = 0; i < array.length; i++) { if (checkOdd(array[i])) { array.splice(i, 1); i--; } } The provided code snippet examines a ...

Which is better: specifying Node.js version with nvmrc or in package.json engines

Ensuring that other developers working on my JavaScript project use specific versions of node and npm is important to me. I recently added the following code snippet to my package.json file: "engineStrict" : true, "engines": { "node" : "10.10.0", ...

Creating a set of labels using values derived from a collection of objects

Looking for advice on how to loop through a Serialized JSON string using an ajax call in JavaScript. I have 8 labels set up and want to assign each key and value from the JSON string to a different label. Any guidance or feedback is appreciated! I'm ...

Why is the value in my React Redux state not updating as expected?

I recently started learning react js as a beginner. To practice, I created a crud app and integrated firebase for authentication. However, I'm facing an issue where I'm not able to retrieve the updated value. Index.jsx At line 11, I'm stru ...

Using React to insert a link with JSX variables

When inserting normal HTML elements with React variables in JSX, there are a few ways to go about it. One option is to use the dangerouslySetInnerHTML attribute or you can utilize a package like html-react-parser from npm. The following code demonstrates ...

Is there a way to keep the selected option in handlebar permanently, even after multiple page refreshes?

I am having trouble implementing the drop-down menu option in handlebars using jQuery. Therefore, I have opted to use the select-options menu instead. Here is the code snippet: <select name="sources" id="sources" class="custom-s ...

The empty string is not getting recognized as part of an array

Currently, I have a textarea field where pressing enter submits and creates a new item in the array. Pressing shift + enter creates a new line in the textarea input field. But when trying to submit by pressing shift and enter after creating a new line, it ...

Validation of form - It is mandatory to fill at least one of the three fields

I rely on form validation from a fantastic source called to ensure my forms are accurate and complete. Within my form, I have three separate phone number fields but it is necessary for at least one of them to be filled in by the user. How can this requir ...

Incorrect positioning on canvas

Is there a way to adjust text alignment within a canvas? Currently, my text is centered. However, when I change the text size, the alignment gets thrown off. Here is the code snippet: <canvas id="puzzle" width="480" height="480"></canvas> ...

Retrieving the attribute for a chosen value from an asp:RadioButtonList using jQuery

I am currently maintaining an old C# codebase and encountering an asp:RadioButtonList... <asp:RadioButtonList AutoPostBack="false" TextAlign="Right" RepeatDirection="Horizontal" RepeatLayout="Flow" runat="server" ID="radIncidentType" /> ...that is ...

There appears to be an unspecified parameter in the controller related to the ng

After fetching data from an API, I use it to populate a form with cascading select fields. I have two functions in place to filter the array based on the selected options, but I am running into an issue where I cannot access properties from ng-model. For ...

Error: React Js is unable to access property 'protocol' because it is undefined

How can I correctly display author.name data from a JSON file in React JS? I am encountering an error while trying to run the code and I'm new to React, so any guidance on resolving this issue would be appreciated. Additionally, I have included an ima ...

JavaScript constants implemented in a script file

Similar Question: Passing a PHP string to a Javascript variable (and escaping newlines) I recently completed a project, but now I need to make one more modification by adding language constants in my JavaScript files. For example, if we include a Jav ...

The positioning of the Material Ui popover is incorrect

I am currently working on a web application project with React and have implemented Material UI for the navbar. On mobile devices, there is a 'show more' icon on the right side. However, when I click on it, the popover opens on the left side disp ...

What is the best way to fix the "Module not detected: Unable to locate [css file] in [directory]" error when deploying a Next.js website on Netlify?

Trying to deploy my site on Netlify from this GitHub repository: https://github.com/Koda-Pig/joshkoter.com, but encountering an error: 10:02:31 AM: Module not found: Can't resolve '../styles/home.module.css' in '/opt/build/repo/pages&ap ...

Preventing typing by detecting keypresses in a text input

I'm trying to set up a text input field so that it triggers a function when the Enter key is pressed. I currently have an if condition to check for the Enter key press, but this prevents users from typing in the input box. What should I include in the ...

I simply aim to remove a single piece of news at a time, yet somehow I manage to delete more than intended

Do you have a PHP file containing a list of news items fetched from the database? Each news item has a delete link, which looks like this: echo '<a id="'.$result_news['id_news'].'" class="j_newsdelete" href="#">Delete</a ...

Ways to delay the inner function's output?

Need help with making a function return only after its inner function is called. See below for the code snippet - function x() { function y() { // Inner function logic } return result; // This should be returned only after function y is ca ...

Interested in halting the code execution once a match is found?

In Angular JS, I have developed a service method that checks whether any of the potential statuses in an array (pendingApplications) match any of the set statuses in another array (applicableStatuses). In order for this to function correctly, the method ...