What is the best way to utilize an Angular service method from a controller?

As a newcomer to Angular, I have created an 'Employee Search' Service module. Let's take a look at the code:

// Employee Search Service
app.service('employeeSearchService', function($http, resourceServerAddress){
    this.empList = [];

    // Method to clear the employee search list
    this.clearEmpList = function(){
        this.empList = [];
    }

    // Method to fetch the employee search list
    this.fetchEmpList = function(){
        return this.empList;
    }

    // Method to perform an employee search
    this.searchEmpList = function(empName){
        var postData = {
                    empName:empName,
                };

        $http({
            method: 'POST',
            url: resourceServerAddress,
            data : postData
        }).then(function successCallback(response) {
            console.log('Response Data : '+response);

            if(response['data']['status'] === 'success'){
                console.log('Response received successfully with status=success');

                if(response['data']['data'].length)
                {
                    console.log('matches found for employee search');
                    this.empList = response;
                }
                else
                {
                    console.log('no matches found for employee search');
                    this.empList = [];
                }
            }

            if(response['data']['status'] === 'error'){
                console.log('Response received successfully with status=error');
            }

        }, function errorCallback(response) {
            console.log('Error occur at time of processing request');
        });
    }
});

Next, in my Controller, I am using the following code to retrieve data from the Service module.

employeeSearchService.searchEmpList(empName);
empSearchResponseList = employeeSearchService.fetchEmpList();
console.log('Data received from server module : '+empSearchResponseList);

While I can see the data and console messages from the service module in Chrome console, I am unable to capture that data in the Controller variable.

I suspect that the way I am using 'searchEmpList()' & 'fetchEmpList()' in my controller may not be correct. I am struggling to find out how to modify it.

Seeking some guidance!

--- Updated Controller Code ---

// Controller for application Home route
app.controller("HomeController", function($scope, $state, $location, $ionicHistory, $ionicSideMenuDelegate, $http, resourceServerAddress, employeeSearchService) {

    console.log('At home controller');

    // Check application session. If none exists, redirect user to login page
    if(window.localStorage.getItem("access_token") === "undefined" || window.localStorage.getItem("access_token") === null) {
        $ionicHistory.nextViewOptions({
            disableAnimate: true,
            disableBack: true
        });

        console.log('Redirecting user to login page');
        $state.go("login");
    }

    $scope.empName               = '';
    $scope.alertMsgBox           = false;
    $scope.alertMsgText          = '';
    $scope.employees             = [];
    $scope.resourceServerAddress = resourceServerAddress;

    var empSearchResponseList=null;

    // Method for searching employees
    $scope.searchEmployee = function(form){
        console.log('Employee name entered : '+$scope.empName);
        console.log('Length of employee name : '+$scope.empName.length);

        if($scope.empName.length >= 3 ){

            var postData = {
                    Emp_Name:$scope.empName,
                    access_token:window.localStorage.getItem('access_token'),
                    session_id:window.localStorage.getItem('session_id')
                };

            $http({
                method: 'POST',
                url: resourceServerAddress,
                data : postData
            }).then(function successCallback(response) {
                console.log('Response Data : '+response);

                if(response['data']['status'] === 'success'){
                    console.log('Response received successfully with status=success');

                    if(response['data']['data'].length)
                    {
                        console.log('matches found for employee search');
                        $scope.employees   = response['data']['data'];
                        $scope.alertMsgBox = false;
                    }
                    else
                    {
                        console.log('no matches found for employee search');
                        $scope.alertMsgBox  = true;
                        $scope.employees    = [];
                        $scope.alertMsgText = 'No matches found.';
                    }
                }

                if(response['data']['status'] === 'error'){
                    console.log('Response received successfully with status=error');
                }

            }, function errorCallback(response) {
                console.log('Error occur at time of processing request');
            });
        }
    }


    // Method to display employee profile
    $scope.showEmpProfile = function(empId){
        console.log('Clicked on profile image of employee ID : '+empId);

        // Redirect to home page
        $state.go('app.emp-profile', {empId:empId});
    }
});

Answer №1

this is really puzzling for me. the $http call happens asynchronously, so when you invoke fetch, it ends up fetching an empty array. I propose something like this:

this.searchEmpList = function(empName){
    var postData = {
                empName:empName,
            };

    return $http({
        method: 'POST',
        url: resourceServerAddress,
        data : postData
    }).then(function(response) {
        console.log('Response Data : '+response);

        if(response['data']['status'] === 'success'){
            console.log('Response received successfully with status=success');

            if(response['data']['data'].length)
            {
                console.log('matches found for employee search');
                return response['data']['data'];
            }
            else
            {
                console.log('no matches found for employee search');
                return [];
            }
        }

        if(response['data']['status'] === 'error'){
            console.log('Response received successfully with status=error');
        }

    }, function(response) {
        console.log('Error occur at time of processing request');
    });
}

and in the controller

employeeSearchService.searchEmpList(empName).then(function(data){
    console.log('data is ready', data);
});

Also note that you need to return the $http to utilize .then() in the controller (returns a promise).

For a comprehensive styleguide on Angular, refer here

Answer №2

Do you have faith in the functionality of your service? I am inclined to use the following code structure:

  .service('Service', function () {
    var Service = {
        //insert methods here
    }
    return Service;
  });

Furthermore, there is no need for extensive utilization of 'this'.

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

Odd behavior observed while running npm scripts in the npm terminal

Included in my package.json file are the following dependencies: "devDependencies": { "chromedriver": "^2.37.0", "geckodriver": "^1.11.0", "nightwatch": "^0.9.20", "selenium-server": "^3.11.0" }, "scripts": { "e2e": "nightwatch -c test ...

Unable to properly zoom in on an image within an iframe in Internet Explorer and Google Chrome

My image zoom functionality works perfectly on all browsers except for IE and Google Chrome when opened inside an iframe. Strangely, it still functions flawlessly in Firefox. How can I resolve this frustrating issue? The image link was sourced from the i ...

In order to ensure proper alignment, adjust the width of the select element to match the width of the

Is there a way for the select element to adjust its width based on the length of the selected option? I want the default option value's width to be shorter, but once another option is selected, I'd like the select element to resize itself so that ...

Troubleshooting ECONNREFUSED in NextJS API: App successfully runs in both deploy and development mode, but encounters issues when next build is executed

Detailing the Glitch I've developed an application using NextJS that incorporates an internal API, utilizing the getStaticProps methods to interact with the API. You can access the live app at this link: Additionally, you can find the project' ...

Why is it important to have specific property names?

Here is some code and HTML for triggering a radio button. It seems to work fine without any issues, but I'm wondering if the presence of a name property is necessary. When I remove the name property, it stops working. Can someone explain why? <inp ...

Error: The reference property 'refs' is undefined and cannot be read - Next.js and React Application

Here is my code for the index page file, located at /pages/index.js import { showFlyout, Flyout } from '../components/flyout' export default class Home extends React.Component { constructor(props) { super(props); this.state = {}; } ...

Ways to access dropdown menu without causing header to move using jQuery

Greetings everyone, I am currently working on a dropdown language selection feature for my website. The issue I am facing is that when I click on the language dropdown in the header, it causes the height of the header to shift. $('.language- ...

The render function is not being executed due to a disruption in the code flow

Within the given code snippet, there is a peculiar issue with the render function being called inside the loop below. Strangely, the console.log statement before the function call executes successfully, but the one directly inside the function does not s ...

AngularJS $scope changes not reflecting in the view

Struggling with a persistent issue in my angularJS $scope. I've been working on updating an array within a controller function, and even though the values are changing based on console logs, the view isn't reflecting those changes. Here's wh ...

How can I uniquely identify and edit individual cells within an ng-grid using the bgColor property?

I need some clarification regarding Angularjs ng-grid. Is there a way to distinguish between the edit-cell and non-edit-cell in ng-grid? Perhaps using different background colors? ...

I'm just getting started: an image carousel featuring a unique twist with random quote overlays, but there's a catch - it only activates on the very first image... what comes next?

After successfully displaying the generator over the first image, I encounter a problem with the second and third images where it seems to disappear. However, upon cycling back to the first slide, the generator reappears with a different quote. I've a ...

Trouble with the ejs <%- body %> rendering properly

I plan to utilize a predefined layout template named layout.ejs, and here is the code present in the file: <html> <head> <title></title> </head> <body> <%- body %> </body> </html> Currently, I ...

What is the process for generating an HTTP response that results in a pipe error being thrown

In my NestJS application, I have created a custom pipe that validates if a given value is a valid URL. If the URL is invalid, an error is thrown. This pipe is utilized in a controller to save an item into the database. Recently, I discovered that the pipe ...

What could be causing the JSON String decode error to occur while utilizing extjs ajax?

Here is an example of my code: Ext.Ajax.request({ url:'test.jsp', params:{id:id,password:password}, success:function(response){ console.log(response); var results = Ext.util.J ...

`Incompatibility with Internet Explorer causes AJAX loader GIF to fail when using asynchronous POST requests`

Is there a way to display an AJAX loader gif during an asynchronous POST request on Internet Explorer? It seems that the request process stalls and the updated content is not visible when using Internet Explorer. However, everything works fine on browser ...

The combination of React and Redux with the utilization of combined reducers

Hey there, I'm currently utilizing thunks to retrieve data from my backend, but I'm a bit uncertain on how to implement it in my combined reducer. Here are my types: export const FETCH_SUCCESS = 'FETCH_SUCCESS'; export const FETCH_FAI ...

Order Up: Vue Draggable Next feature keeps your lists in line

I need to maintain the order of two lists in local storage so that their positions are saved and retrieved between sessions. In my Vue 3 TS project, I am utilizing this library. Check out the code snippet below: <template> <div> <h3> ...

What is the reason for not receiving a JSON object in the response from my personal node.js/express server?

-- Exploring a New Challenge -- I am currently working on creating an e-form signup for a client as part of our business marketing strategy service. The form design is complete and looks excellent. Now, I need to connect it to the existing API that our bu ...

Dealing with validations in a personalized aid

Recently, I've been exploring CodeceptJs and have found it quite easy to work with. Currently, I'm utilizing it with NightmareJs for testing a gallery that retrieves data from an interface via JSONP to create a list of images enclosed in <div& ...

Having trouble invoking html2canvas within an AngularJS app

When I define html2canvas functions in my controller, the alert in html2canvas doesn't get fired and my canvasToImageSuccess function is not executed. Am I missing something here? In my controller, I have defined html2canvas functions as shown below ...