Why does setting the variable value as an argument in an AngularJS function result in the variable becoming undefined?

The following is the Main Controller implementation:

angular.module("HomePageApp", ["BaseApp"])
    .controller("MainCtrl", ["$http", "$window", "BaseService", function($http, $window, BaseService) {

        var self = this;

        self.posts = BaseService.fetch['YPosts']();
        self.logoutUser = function() {
            console.log(self.posts);
            BaseService.logout();
        };

    }]);

This is my BaseService code snippet (some return objects are omitted for simplicity):

angular.module("BaseApp", [])
    .config(['$httpProvider', function($httpProvider) {
        $httpProvider.defaults.xsrfCookieName = 'csrftoken';
        $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
    }])

    .config(['$locationProvider', function($locationProvider){
        $locationProvider.html5Mode(true);
    }])

    .factory("BaseService", ["$http", "$window", function($http, $window) {
        var cerrorMessages = [];
        var posts = {};
        return {

        fetch: {
            XPosts: function() {
                $http.get('/postsX/')
                .then(function(response) {
                    posts = response.data;
                }, function(response) {
                    posts = {};
                    cerrorMessages = BaseService.accessErrors(response.data);
                });
                return posts;
            },

            YPosts: function() {
                $http.get('/postsY')
                .then(function(response) {
                    posts = response.data;
                    console.log(posts);
                    return posts;
                }, function(response) {
                    console.log('here');
                    posts = {};
                    cerrorMessages = BaseService.accessErrors(response.data);
                });
            }
        }
    };
}]);

When inspecting the posts in the BaseService, it contains objects. However, upon clicking the logout button (which also inspects posts), it reports that it is undefined. Any insights into why this might be happening?

Answer №1

When using a return statement, it will only exit the current function's scope. In JavaScript, it is common to pass callbacks to functions that take a long time to execute in order to prevent blocking other activities. To get the value of 'posts' after the GET request has been resolved, you can modify the 'YPosts' function to accept a callback parameter:

        YPosts: function(callback) {
            $http.get('/postsY')
            .then(function(response) {
                posts = response.data;
                console.log(posts);
                callback(posts);
            }, function(response) {
                console.log('here');
                posts = {};
                errorMessages = BaseService.accessErrors(response.data);
            });
        }

Note:

To call the 'YPosts' function with the updated callback method, use the following syntax:

BaseService.fetch.YPosts(function(posts) {
    self.posts = posts;
});
// Please keep in mind that the callback will not be executed until the request completes,
// so 'self.posts === undefined' outside of this block

Answer №2

When using the then() function within your YPosts, it's important to note that returning a value there is different from returning a value from XPosts. Similarly, simply returning posts within XPosts won't work as expected because the value may not have been set yet due to the asynchronous nature of $http.get.

To address this issue, you can either introduce another callback as suggested in lyjackal's answer or ensure you are utilizing the existing one correctly:


       YPosts: function() {
            return $http.get('/postsY')
       }

Additionally, make sure to handle data retrieval and manipulation properly by structuring your code like so:


    var self = this;
    BaseService.fetch.YPosts().then(
        function(response) { 
            self.posts = response.data; 
        },
        function(response) { 
            // error handler logic here
        }
    );

    self.logoutUser = function() {
        console.log(self.posts);
        BaseService.logout();
    };

It's worth noting that if the logoutUser function is invoked before YPosts has finished fetching data, the console.log(self.posts) will display undefined once again.

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

eslint is designed to not handle multiple package.json files

There are two package.json files in my project root folder └ app ---- /public └ /styles └ /src └ package.json └ eslintrc.json └ webpack.config.js └ server - /something └ /something ...

Removing the last two characters from a number with a forward slash in Vue.js

I'm encountering a slight issue with my code: <template slot="popover"> <img :src="'img/articles/' + item.id + '_1.jpg'"> </template> Some of the item.id numbers (Example: 002917/1) contain ...

Binding the Ionic v3 page with Ionic framework

I need to bind an ionic input component to an html page from a ts file, but it is only displaying text. Here is my html code: <div class="one" [innerHtml]="htmlToAdd"></div> This is the code in my ts file: constructor(public sanitizer: DomS ...

How can I specifically activate the keydown event for alphanumeric and special characters in Angular7?

I am looking to create a keydown event that will be triggered by alphanumeric or special characters like #$@. <input type="text" style="width: 70%;" [(ngModel)]= "textMessage" (keydown) ="sendTypingEvent()" > However, I want to prevent the event ...

Switch between TrackBall and FlyControls in threejs to change the type of controls being used

My goal is to implement two different control modes in my project: a free "flying" mode and an object-centered (trackball) mode. I want to seamlessly switch between them with the press of a button. Initially, I experimented with TrackBallControls and FlyC ...

Is it beneficial to display three.js on a <canvas> rather than a <div>?

I have come across examples in three.js that use: renderer = new THREE.WebGLRenderer( { canvas: document.querySelector( 'canvas' ) } ); This relates to a <canvas></canvas> element. On the contrary, there is another method: rendere ...

Loop through the elements retrieved by the `getElementsByName` method in

My goal is to access each node by elementName using the following JavaScript code: function myFunction() { var h1 = document.getElementsByName("demoNode"); for (var i = 0; i < h1.length; i++) { if (h1[i].name == "demoNode") { var att ...

Utilizing Route Parameters in Node.js

frontend.jade doctype html html head meta(charset='utf-8') //if lt IE 9 script(type='text/javascript', src='http://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js') // [if gte IE 9] <! scr ...

How to create a manual mock for @material-ui withStyles in React using Jest

I have been experimenting with creating manual mocks for the @material-ui/core/styles module, specifically targeting the HOC known as withStyles. Initially, using an inline mock with jest.mock function worked flawlessly. However, when attempting to reloca ...

Angular JS Error: Unable to find the registered controller named 'myCtrl1' due to [$controller:ctrlreg] error

This is a snippet of Angular code that I've been working on, but when I try to run it, I encounter the following error message: Module 'myApp1' is not available! You either misspelled the module name or forgot to load it. Here's the c ...

Use CodeMirror on an existing div element

My div named "content_editable" is the center of my code editing application. I need it to adhere to specific CSS dimensions, but I also want to integrate CodeMirror syntax highlighting into it. However, following the documentation's instructions does ...

Discovering a device's model using JavaScript

How can I use Javascript to redirect users to different download pages based on their device model? ...

What is the best way to resize a div located below a dynamic div in order to occupy the available space?

My website has a dynamic div1 and a scrollable table inside div2. I need the div2 to take up the remaining height of the window, while ensuring all divs remain responsive. I've tried using JavaScript to calculate and adjust the heights on window loa ...

One function is failing to execute properly due to multiple if conditions

Take a look at my JavaScript code below: function showLater1() { if ((vidos.currentTime >= 30) && (vidos.currentTime <= 34)) { lay.style.opacity = "1"; content.style.opacity = "0"; controls.style.opacity = "0"; ...

What is preventing the DELETE and PUT methods from functioning on my website?

I am in the process of creating a simple website that functions as a task management application. Each HTTP method has one endpoint, and the methods being used are GET, POST, PUT, and DELETE. These methods need to be linked to functionalities such as addin ...

Adding animation to a div that is being appended can be done by using JavaScript functions and

I am looking to incorporate animation into my title div. Below is the HTML code I have so far: <div class="particles" id="tittle"> <!-- Displaying title from Firestore using JavaScript --> </div> Here is the CSS cod ...

What are the typical situations in which Node.js is commonly used?

Do you believe that a majority of node.js users primarily utilize npm? What do you think are the most prevalent use cases for node.js apart from npm? ...

Creating sleek flat buttons using WebixWould you like to learn how to

From what I've observed, the default buttons in webix appear a certain way. In a demo, I noticed "flat" type buttons that look different: Is there a way to customize my navigation buttons to look like that? I couldn't find any information about ...

I am setting up two data picker fields: the first one should display the date as 01/01/2022, while the second field should show today's date

https://i.sstatic.net/jsTme.png In my project, I am working on setting up 2 input date fields: 1.1. The first field is for the start date and it should automatically display as: 01/01/current-year(For example, if the current year is 2022, then it would sh ...

Utilizing ng-repeat Loop Variable in ng-include Content within Angular Framework

I am looking to create two tables with identical record structures. One table will serve as the Main table, while the other will act as an Archive. Each record is represented by bootstrap divs with col-sm-x structure containing details such as {{rec.Name}} ...