An error of undefined Angular Service/Factory has occurred

I created a factory service called siteCollection:

spApp.factory('siteCollection', function(){
  return {
    usersObject : [],
    getUsers : function (){
      $().SPServices({
        operation: "GetUserCollectionFromSite",
        completefunc: function(xData, Status) {
          var responseXML = $(xData.responseXML);
          responseXML.find("User").each(function() {
            usersObject.push({
              id: $(this).attr("ID"),
              name: $(this).attr("Name"),
              domainAccount: $(this).attr("LoginName")
            });
          });
        }
      });
      return usersObject;
    }
  }
})

The intention is to return the usersObject that I defined at the beginning, but I'm encountering an undefined error in the console for the object.

Below is the controller code:

spApp.controller('userCtrl', 
    function userCtrl($scope,siteCollection){
        $scope.users = siteCollection.getUsers();
    }
);

I am still learning Angular and navigating through the challenges.

Answer №1

There are a couple of issues to address in your code:

The first problem: within your factory, you are returning an object with the properties usersObject and getUsers. However, in the getUsers function, you are trying to access a variable named "usersObject", which is not a property of the returned object. To fix this, declare the variable outside as shown below:

var usersObject = [];
return {
  getUsers: function () {
    // ...
    return usersObject;
  }
};

The second issue: you are populating your usersObject within a callback function that is executed asynchronously. AngularJS does not automatically detect these changes in your array. To ensure the views are updated after the data has been added to the array, consider using $rootScope.$apply() as demonstrated below:

spApp.factory('siteCollection', function ($rootScope) {
  // ...
  $rootScope.$apply(function () {
    responseXML.find("User").each( function () { ... } );
  });
}

Although using $rootScope.$apply() works, a cleaner approach would be to utilize promises. Rewrite your code with promises like this:

spApp.factory('siteCollection', function ($q) {
  return {
    getUsers : function (){
      var deferred = $q.defer();

      $().SPServices({
        operation: "GetUserCollectionFromSite",
        completefunc: function(xData, Status) {
          var responseXML = $(xData.responseXML),
              usersObject = [];

          responseXML.find("User").each(function() {
            usersObject.push({
              id: $(this).attr("ID"),
              name: $(this).attr("Name"),
              domainAccount: $(this).attr("LoginName")
            });
          });

          deferred.resolve(usersObject);
        }
      });

      return deferred;
    }
  }
});

If you adopt the promise-based approach, remember to include the following in your controllers to handle the loaded data appropriately:

siteCollection.getUsers.then(function (users) {
  // Handle the data here
});

Answer №2

Here is the suggested format:

app.factory('friendsList', function(){
  var contactsArray = [];
  return {
    getContacts : function (){...

The returned object consists of methods to interact with the data, however they lack cohesion in terms of their scope. By defining only the `contactsArray` within the return object, it becomes inaccessible within `getContacts`.

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

Is it possible to reset only certain data values in Vue without re-initializing the entire set?

In the development process, we often encounter the need to re-initialize data structures. One common method is as follows: function initialData() { return { is_active: true, is_collapsed: true, resetable_data: 'value' ...

Creating dynamic templates for table rows in AngularJS directives

Is it possible to dynamically load an AngularJS Directive templateUrl while working within a table? In my scenario, I have the following HTML structure where I am repeating a tr element with a fw-rule directive: <tbody> <tr ng-repeat="rule in ...

Transferring information and storing it in a textbox

I have a homepage that features a popup window. <textarea class="form-control item"></textarea> <button type="button" class="btn btn-primary" name="name">Send</button> Additionally, there is a secondary page at (/conclusion/main) ...

PHP is unable to extract an email address from the $http post method in Angular

There seems to be an issue with the email address not being received properly when posted to the server. The @ symbol is causing the problem, while the rest of the email address appears fine. angular: $http({ method: 'POST', ...

Tips for ensuring an HTML element remains within defined boundaries

Currently working on a visualization tool for search algorithms using React, I've encountered a minor issue when moving the start or end nodes. Upon clicking and dragging the mouse across the grid, the nodes adjust accordingly until reaching the grid& ...

Guide on updating the form structure with ajax

Lately, I've been working on a contact module with 3 columns: name, email, and phone. There's also a +1 button that adds a new row to input another contact using ajax. However, a problem arises when updating the structure as the data in the old c ...

Could we confirm if this straightforward string is considered valid JSON data?

There are numerous intricate questions on Stack Overflow about whether a complex structure is considered valid JSON. However, what about something much simpler? "12345" Would the provided code snippet be considered valid JSON? ...

What are the steps for including and excluding components in Parallax JS?

When working with Parallax JS: I am trying to modify the components within the <li> tags of my menu, but I am unsure how to do so without restarting the plugin. I cannot seem to find the destroy command. Currently, I am using the JQuery version of ...

Personalizing the text of an item in a v-select interface

Can the item-text be customized for the v-select component? I am interested in customizing each item within the v-select dropdown, similar to this example: :item-text="item.name - item.description" ...

Change the background color of a particular row in a table using Vue.js to be red

I am having an issue with a regular table - when I click on a specific row, I want only that row to turn red. Below is the code snippet that I have attempted: <tr role="row" v-for="(proxy, key) in this.ProxiesList" @click.prevent=&q ...

Resolver for nested TypeORM Apollo queries

I've set up a schema that includes database tables and entity classes as shown below: type User { id: Int! phoneNumber: String! } type Event { id: Int! host: User } Now, I'm attempting to create a query using Apollo like this ...

Looping through a series of JavaScript objects in a JSON

I've encountered an issue when trying to run a loop with a JSON query inside it. Here's what my code looks like: for (var i = 0; i < numitems; i++) { var currentitem = items[i]; $.getJSON("http://localhost/items.php", {'itemname&ap ...

Transferring information from child to parent class in TypeScript

I have a scenario where I have two classes (Model). Can I access properties defined in the child class from the parent class? Parent Class: class Model{ constructor() { //I need the table name here. which is defined in child. } publ ...

Issue with Material UI dropdown not selecting value on Enter key press

I have encountered an issue with the material UI dropdown component that I am using. When I navigate through the dropdown options using arrow keys and press enter, the selected value does not get highlighted. Below is the code snippet for the dropdown: ...

What is the best way to define a variable in EJS?

I need to populate my database array results on the frontend using EJS. The code snippet I'm using is as follows: var tags = ["<%tags%>"] <% for(var i=0; i<tags.length; i++) { %> <a href='<%= tags[i] %&g ...

Try utilizing MutationObserver to monitor changes in various nodes

I am faced with a situation where I have elements in my HTML that are dynamically populated with text from an API. My goal is to check if all these elements have a value and then trigger a function accordingly. The current code I have only allows me to obs ...

When testing on jsfiddle, the script functions properly with pure JavaScript. However, when integrating it into my own code, it fails to work unless jQuery is included

Visit this link to access the code snippet. Below is my code: const chk = document.getElementById('chk'); const body = document.body; $(function(){ chk.addEventListener('change', () => { $('.body').toggleClass( ...

Using Javascript function with ASP.NET MVC ActionLink

I need help with loading a partial view in a modal popup when clicking on action links. Links: @model IEnumerable<string> <ul> @foreach (var item in Model) { <li> @Html.ActionLink(item, "MyAction", null, new ...

Reduce the length of the text to 50 characters after the current word, while ensuring that the word

Looking for a way to shorten text after reaching 50 characters, making sure not to split words in the middle when cutting off. For example: Contrary to popular belief, Lorem Ipsum is not simply text (59 chars) Desired output: Contrary to popular belief, ...

Storing user information in Angular after login and implementing JWT authentication

Is it advisable to save any user information other than JWT in local storage or cookies after a successful login? (The user profile object is already saved and encrypted in the JWT payload sub-part.) I need the user profile object ready before initializing ...