ui-sref unable to access controller information or view

I'm experiencing some difficulty accessing the controller for my state param. I've made sure to use the correct state to link to the next view.

 <td><a ui-sref="orders({customerId: cust.id})">View Orders</a></td>

In my config file, I have defined the state name and the route params. I have temporarily commented out the resolve object. My objective is to enter the controller and pass the correct data. It's important to note that I am using controllerAs

Initially, I tried ({customerId: ctrl.cust.id }) , but this did not change the URL route. The URL is updating to match the URL name but is failing to connect to the controller and display the view.

    (function() {
        'use strict';

        angular
            .module('app.orders')
            .config(config);

        function config($stateProvider) {
            $stateProvider
                .state('orders',{
                    // params: {customerid: null},
                    url:'/customers:customerId', 
                    templateUrl: './components/orders/orders.html',
                    controller: 'OrdersController',
                    controllerAs: 'ctrl',
                    resolve: {
                    customerFactory: 'customerFactory',
                    customerInfo: function( customerFactory, $stateParams) {
                    return customerFactory.getCustomers($stateParams.id);
                }

            }

************** my main problem is the resolve. This is blocking me from getting into the next controller. *****************

                    resolve: {
                        customerId:[ '$stateParams','customerFactory', function( $stateParams, customerFactory) {
                             return customerFactory.getCustomers($stateParams.id);
                         }]
                     }
            })
        };
})();

Currently, my controller is very basic. I just want to establish a connection to it. I have checked the network tab in the browser developer tools and can see GET requests for the files.

  (function() {
    // 'use strict';
    angular
        .module('app.orders')
        .controller('OrdersController', OrdersController);

    function OrdersController($stateParams) {
        console.log('in');
            var vm = this;
            vm.title = "Customer Orders";
            vm.customer = null;
    }
}());

I have included my module in the main JavaScript file.

   (function () {
    'use strict';

    angular.module('app', ['app.services',
        'app.customers',
        'app.orders','ui.router']);
})();

When I comment out the resolve section, I can access the controller. Therefore, I know the issue lies within the resolve functionality. Here is my service code. I'm fetching data from a JSON file using an $http request and handling the response with .then

Updates: Here is the modified service call. I am successfully retrieving the correct customer data in the console each time.

  (function() {
    angular
        .module('app.services',[])
        .constant('_', window._)
        .factory('customersFactory', customersFactory);

    function customersFactory($http, $log) {

        return {
            getCustomers: getCustomers,
            getCustomer: getCustomer
        };
        function getCustomers(){
            return $http.get('./Services/customers.json',{catch: true})
                .then(getCustomerListComplete)
                .catch(getCustomerListFailed);

                function getCustomerListComplete(response) {
                    console.log('response.data',response.data);
                    return response.data;
                }

                function getCustomerListFailed(error) {
                    console.log('error', error);
                }
        }

        function getCustomer(id) {
            var url = './Services/customers.json';
            return $http.get(url, {
                catch: true
            })
            .then(function(response) {
                console.log('promise id',id);
                var data = response.data;
                for(var i =0, len=data.length;i<len;i++) {
                    console.log('data[i].id',data[i].id);
                    if(data[i].id === parseInt(id)) {
                        console.log('data[i]', data[i]);
                        return data[i];
                    }
                }
            })
        }
    }
}());

Answer №1

Feel free to explore a live example using your code

It can be quite challenging to pinpoint the issue. After reviewing the suggestions provided in this post related to an error in ui-sref functionality, it appears that your code is indeed correct and valid.

I have placed your content within the app.orders.js file (with only one modification made to the templateUrl path for demonstration purposes):

Updated Angular Module and Configuration
'use strict';

angular 
    .module('app.orders')
    .config(['$stateProvider', config]); 

//config.$inject = ['$stateProvider'];
function config($stateProvider) {
    $stateProvider
        .state('orders',{
            // params: {customerid: null},
            url:'/customers:customerId', 
            //templateUrl: './components/orders/orders.html',
            templateUrl: 'components/orders/orders.html',
            controller: 'OrdersController',
            controllerAs: 'ctrl'
            // resolve: {
            //     customerId:[ '$stateParams','customerFactory', function( $stateParams, customerFactory) {
            //         return customerFactory.getCustomers($stateParams.id);
            //     }]
            // }
    })
};

Updated Orders Controller
angular
    .module('app.orders')
    .controller('OrdersController', OrdersController);

OrdersController.$inject = ['$stateParams'];
function OrdersController($stateParams) {
    console.log('in');
        var vm = this;
        vm.title = "Customer Orders " + $stateParams.customerId;
        vm.customer = null;
}

Here is the functioning template components/orders/orders.html code snippet:

<div >
  <h3>current state name: <var>{{$state.current.name}}</var></h3>

  <h5>title</h5>
  <pre>{{ctrl.title}}</pre>
  ...

To trigger this functionality, use the following call:

<li ng-repeat="cust in [{id:1}, {id:2}]"
    ><a ui-sref="orders({customerId: cust.id})">View Orders - cust ID == {{cust.id}}</a>
</li>

See it in action by clicking on this link

Answer №2

While my previous solution focused on making the state work without resolve, we will now explore some adjustments and a fix to enable resolve functionality.

A functioning plunker has been created as an extension of the previous example.

Corrections Made:

The primary fix involves modifying this particular definition:

angular
    .module('app.services',[])
    .factory('customersFactory', customersFactory);

Note the change in naming convention with 'customersFactory'. As opposed to:

...my main issue is with the resolve function that is hindering progress to the next controller....

resolve: {
  customerId:['$stateParams','customerFactory', function($stateParams, customerFactory) {
    return customerFactory.getCustomers($stateParams.id);
  }]
}

We are referencing 'customerFactory' (singular form, no middles) here.

Additional Enhancements:

Here's an updated version of our state definition:

$stateProvider
    .state('orders',{
        url:'/customers{customerId:int}',
        templateUrl: './components/orders/orders.html',
        controller: 'OrdersController',
        controllerAs: 'ctrl',
        resolve: {
          customer:['$stateParams','customersFactory', 
            function($stateParams, customersFactory) {
              return customersFactory
                .getCustomer($stateParams.customerId)
                ;
            }]
          }
})

Below is the enhanced factory containing a new method getCustomer:

angular
  .module('app.services', [])
  .factory('customersFactory', customersFactory);

customersFactory.$inject = ['$http', '$log', '$q', '$stateParams'];

function customersFactory($http, $log, $q, $stateParams) {

  return {
    getCustomers: getCustomers,
    getCustomer: getCustomer
  };

  function getCustomers() {
    // Implementation details can be found in the question or Plunker
  }

  function getCustomer(id) {
    var url = "customer.data.json";
    return $http
      .get(url, {
        catch: true
      })
      .then(function(response){
        var data = response.data;
        var customer = _.find(data, {"id" : id});
        return customer;
      })
      ;
  }
}

JSON data structure used:

[
  {
    "id" : 1, "name": "Abc", "Code" : "N1"
  },
  {
    "id" : 2, "name": "Def", "Code" : "N22"
  },
  {
    "id" : 3, "name": "Yyz", "Code" : "N333"
  }
] 

Implementation inside the controller:

OrdersController.$inject = ['$stateParams', 'customer'];
function OrdersController($stateParams, customer) {
    console.log('in');
        var vm = this;
        vm.title = "Customer Orders " + $stateParams.customerId;
        vm.customer = customer;
}

View for displaying customer information:

<h3>customer</h3>
<pre>{{ctrl.customer | json}}</pre>

Experience the changes live here

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

Create a CSS dropdown menu design similar to the one shown in the image

I am seeking guidance on how to replicate the design depicted in this image: https://i.sstatic.net/Hl8HZ.jpg Currently, my menu structure is as follows: body { background: white; margin: 0; padding: 0; } /* / nav */ nav { width: 100%; backgr ...

Halt and anticipate a boolean reply from another function

Is there a way to create two functions in JavaScript, run one of them, then within that function, execute the other and pause until it receives a response (yes or no) before moving on to an if statement? The user's response should be manual. Here is ...

What is the best way to add a key and value into a specific position within a key-value array using jQuery or JavaScript?

Seeking assistance with jQuery - I have a key value array object and need help var myArray= {}; myArray['key1'] = 'value1'; myArray['key2'] = 'value2'; myArray['key3'] = 'value3'; ...

Guide on implementing Webpack and Gulp for transpiling application and test directories with multiple entry points

For a project I'm working on, I decided to build a basic blog. The focus is on honing my skills with React, ES6, and the Mocha test framework. However, I've hit a roadblock when it comes to transpiling my ES6 tests and application code using the ...

Position text fields precisely above the canvas elements

My issue involves positioning two side-by-side canvases within a browser window that the user can resize. I want these canvases to remain centered and not wrap when the window is shrunk, but there's a twist - I also need to collect user information th ...

Concealing a block from top to bottom

I currently have a filter that is hidden when clicked, with a transition effect that moves it from the bottom to the top. I have recorded my screen to demonstrate this behavior: . However, I now need the filter to hide from top to bottom instead, essenti ...

The function is not executing as expected, with no errors detected in the console log

I've been working on this function, but I'm having trouble getting it to run properly. None of my console.log messages are showing up in the console. This function is supposed to validate emails upon submission, but only for a specific domain. ...

Navigating within a class-based component using Next.js: A brief guide

Is it possible to create a redirect from within an onSubmit call while maintaining CampaignNew as a class-based component? I have provided the code snippet below, and I am looking for guidance on achieving this. import React, { Component } from "rea ...

Issue exporting excel file in Angular using ExcelJS: encountering error TS2307 stating "Cannot find module 'stream'" and error TS2503 indicating "Cannot find namespace 'NodeJS'"

Exporting an excel file using ExcelJS has been a challenge for me. When I checked my console in the VS Code terminal, I encountered the following errors: ERROR in node_modules/exceljs/index.d.ts:1398:22 - error TS2307: Cannot find module 'stream&apo ...

Hover over the text to disable the input element and display it as a textbox

Currently, I have a situation where I have two text boxes - when text is entered into textbox1, textbox2 becomes disabled as expected. However, my second requirement is that upon disabling textbox2, hovering over it should display the message "You can ente ...

There are multiple ways to extract a value from Python code and assign it to a JavaScript variable in a JS file

I am currently working on developing the frontend for a voice bot using JavaScript, while the backend is written in Python. if hi == 0: talk('hello iam kavi') print('hello iam kavi Voice assistant') talk('How are you bu ...

Splitting a string in Angular.JS using ng-repeat

Just diving into the world of Angular.JS and grappling with the concept of implementing ng-repeat. Within my scope, I have a data object derived from JSON fetched from my database. Among the returned 'fields', one particular field can either be ...

Layered parallax scenery

I'm interested in creating a parallax effect similar to this example. https://medium.com/@PatrykZabielski/how-to-make-multi-layered-parallax-illustration-with-css-javascript-2b56883c3f27 However, I find the use of HAML and Coffeescript in the mentio ...

Debugging Protractor tests in WebStorm

I attempted to set up protractor debugging in my webstorm and here is the configuration I followed, as mentioned here: https://i.sstatic.net/Te4aq.png This is the content of my protractor.conf file: /*defining all the test files we want to include*/ v ...

Executing function inside an Angular factory

I am currently working with an Angular factory that contains various functions. My goal is to use myService to retrieve data, and upon successful retrieval, call another function within the factory: myApp.factory('myFactory', function($http) { ...

Toggle the visibility of multiple divs depending on a specific attribute value

I previously inquired about this issue, but I believe my wording was unclear and the responses focused on how to display or hide a group of divs when clicking a button. While I understand that concept, my specific challenge is slightly different. Let me pr ...

issue with non-existent value in v-for loop when using functional template refs

Scenario I am currently developing a personalized filtering feature. This feature allows users to add n filters that are shown using a v-for loop in the template. Users have the ability to modify input values and remove filters as needed. Challenge Issue ...

Tips for triggering a method when clicking instead of using v-for in Vue.js

I need help arranging an array of objects based on their ratings. Currently, I am able to display the items from highest to lowest rating using the v-for method. But, I would like to first display the objects in their original order and then have a button ...

Guide on darkening the surrounding div of an alert to give it a modal-like effect

I want to display an alert to the user in a visually appealing way. To achieve this, I am utilizing Bootstrap's alert class. Here is how I am showing the user a div: <div class="alert alert-warning alert-dismissible" role="alert"> Some text ...

Struggling with incorporating a web link into a structured data table

I am currently working on a Django application that utilizes jQuery DataTables to display a list view of items. My goal is to include a hyperlink in the first element of the table, which represents the primary key for the model being displayed. This link s ...