15

I wish to pass a param from one store-state to the display product info in products-state:

My app - storeApp

.config(['$stateProvider', function($stateProvider) {
$stateProvider
    .state('store', {
        url: '/store',
        templateUrl: 'store/store',
        controller: 'storeCtrl'
    })
    .state('products', {
        url: '/products/:productSku',
        templateUrl: 'store/product',
        controller: 'productCtrl',
        resolve: {
                productResource: 'productFactory',
                _product: function(productResource, $stateParams){
                return productResource.getProduct($stateParams.productSku);
                    }
                }

Store.jade

a(href='/products/{{product.sku}}')

Product controller

.controller("productCtrl", function ($rootScope, $http, $stateParams, productFactory, storeFactory) {
//.controller('productCtrl', ['_product', function ($scope, $rootScope, storeFactory, _product) {

console.log($stateParams.productSku);

Product Factory

function getProduct(sku) {
    return $http.get('http://localhost:3000/api/products/' + sku );
}

Since I am using MEAN Stack, node has the router attached to express:

Server.js

const storeController = require('./controllers/store');
server.get('/store/product', passportConfig.isAuthenticated, storeController.getProductPage);

Store.js

exports.getProductPage = (req, res) => {
    res.render('store/product', {
        title: 'PP',
        angularApp: 'storeApp'
    })
}

I tried returning _product but I get Unknown provider: _productProvider <- _product <- productCtrl

I tried using ui-sref - a(ui-sref="products({productSku:'{{product.sku}}'})") in store.jade to send param from store_State to products_State & finally got an object back from API.

Now the issue is that node will not return the view.

Basically what I am trying to achieve is: Node serving client views, all store views - store/ product/ cart are attached to angular app served through Server.js, Clicking store product will redirect to product page after resolve product info from api. I am getting product info but not getting product view.

I looked it up but all solutions did not work....maybe my bad :-(
How can I go about this?

UPDATE-1: this is whats happening: App loads product but does not transfer to view

UPDATE-2: When I pass the control to angular, I have express routing the menu, and angular stateProvider routing/ connecting views to controllers. Main view that loads is the store itself:

app.js - store route

$stateProvider
    .state('store', {
            url: '/store',
            templateUrl: 'store/store',
            controller: 'storeCtrl'
    })

server.js (express)

server.get('/store', passportConfig.isAuthenticated, storeController.getStorePage);

store.js

exports.getStorePage = (req, res) => {
    res.render('store/store', {
        title: 'S--tore',
        angularApp: 'storeApp'
    });
}

store.ctr.js

angular.module("storeApp")
.controller("storeCtrl", function($rootScope, $http, storeFactory) {

    var products;

    storeFactory.getProducts().then(function(_products) {
        products = _products.data;
        $rootScope.products = products;
    });

That loads just fine!

But when I try to send the param productSku from store view to product view and have the resolve send product params back to product view that where it stops working, it's either I get the view OR i get the params.

WebStorm console log snapshot

I tried different ways of resolve, they all result the same - view OR product params.

app.js - product route

.state('products', {
    url: '/products/:productSku',
    templateUrl: 'store/product',
    controller: 'productCtrl',
    resolve: {
        _product: function ($stateParams, $state, $http) {
        return $http.get('http://localhost:3000/api/products/' + $stateParams.productSku );
        //return productResource.getProduct($stateParams.productSku)
        }
    }
})

If I remove the resolve and send a(href='/products/{{product.sku}}') from store.jade I get the template in the route, chrome console error I get is `Error: $injector:unpr Unknown Provider _product <- productCtrl

product.ctr.js

.controller('productCtrl', ['_product', function ($rootScope, $http, $stateParams, productFactory, storeFactory, _product) {

If I send a(ui-sref="products({productSku: product.sku })") with resolve I get product params (shown in WebStorem snapshot above) NO view.

Jadeye
  • 3,551
  • 4
  • 47
  • 63
  • do you have the error of the `ui-sref`? – AranS Aug 07 '16 at 12:42
  • @AranS: `ui-sref` issue has been fixed but now it does not redirect to view after `resolve` product info – Jadeye Aug 08 '16 at 21:16
  • @Jadeye - try `a(ui-sref="products({ productSku: product.sku })")` instead of `a(ui-sref="products({productSku:'{{product.sku}}'})")` – Aks1357 Aug 09 '16 at 20:58
  • @Aks1357, same same, & this is not the issue at hand, `resolve` or any other function on the way is. – Jadeye Aug 10 '16 at 07:18
  • state definition object can have params property and we can pass any object with that param name to that state. – ravshansbox Sep 02 '16 at 09:40

4 Answers4

1

angular will not load jade templates, You will need an html template, The jade template is loaded by express. You might like to try using ui-view like this:

Store.jade

div(ui-view)
  a(href='/products/{{product.sku}}')

Which should make angular look for the unnamed view when loading the route.

Your templateUrl's don't look to be pointing to files, perhaps you're missing the file extension?

Make sure you return a $promise in resolve as ui-router waits until they are resolved before rendering the view.

I'd recommend having named views with corresponding config in route too:

.state('store', {
    url: '/store',
    views: {
        '@': {
            templateUrl: 'store/store.html',
            controller: 'storeCtrl'
        }
    }
})
.state('products', {
    url: '/products/:productSku',
    templateUrl: 'store/product',
    controller: 'productCtrl',
    resolve: {
        _product: function ($stateParams, $state, $http) {
            return $http.get('http://localhost:3000/api/products/' + $stateParams.productSku ).$promise;

    }
}

})

See the docs here: https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views

Adam Spence
  • 3,040
  • 1
  • 21
  • 17
  • `state` store is being served (by express of course) and if I remove the `resolve` and change `ui-sref` to a regular `a(href='/products/{{product.sku}}')` it does produce the `jade template`, the thing is that the `router/ stateProvider/ stateParams` don't get `productSku` – Jadeye Aug 10 '16 at 12:21
  • so do you have a template at store/product and does it get loaded on route change? I think the problem is the lack of ng-view, difficult to say exactly. UI-Router sometimes fails silently which is annoying – Adam Spence Aug 11 '16 at 07:36
  • I do have all in place. I added a snapshot so you can see the console. As you can see the `api` returns the product, the angular says it finished loading the template when actually it is on the same page where the call was mad from. I f I could think where the issue is occuring I would say its with the `ui-sref` sending the param from one `state` to the other (as I mentioned in my question). it resolves the param then calls express to load the view & does not return the view to screen....:-(... possibly something to do with the route in browser URL – Jadeye Aug 11 '16 at 19:25
  • have you tried adding the ng-view wrapper? I'm going to need a plunkr or something to debug properly – Adam Spence Aug 12 '16 at 08:20
  • plunker is a bit of a problem since i have `express` involved, but I will try and add an update to simplify things a bit more. I did try you ng-view wrapper, it didn't help. please read my update. thanx – Jadeye Aug 12 '16 at 14:33
  • shame about plunker but have a look at my latest edit about `$promise`. – Adam Spence Aug 17 '16 at 08:35
0

This is the solution I found:

store.jade

a(href='/products/{{product.sku}}' ng-click='sku(product.sku)')

stroe.ctr.js

$rootScope.sku = function(value){
        storeFactory.singleProduct.productSku = value;
        storeFactory.singleProduct.saveSku();
}

store.fac.js

var singleProduct = {
    productSku : '',
    saveSku: function() {
        sessionStorage.productSku = angular.toJson(singleProduct.productSku);
    },
    getSku: function() {
        singleProduct.productSku = angular.fromJson(sessionStorage.productSku);
        return singleProduct.productSku;
    }
}

product.ctr.js

var sp = storeFactory.singleProduct.getSku();

productFactory.getProduct(sp).then(function (product) {
    $rootScope.product = product.data;
});

product.fac.js

function getProduct(sku) {
        return $http.get('http://localhost:3000/api/products/' + sku );
}

Basically I am storing productSku to sessionStorage and getting it back from there when product.jade view loads...

Thanx to all who tried...

Jadeye
  • 3,551
  • 4
  • 47
  • 63
0

You can pass it as $state.data in your controller.

toState = $state.get("some-state");
toState.data.foo = $scope.foo;
$state.go(toState);
aaronmallen
  • 1,418
  • 1
  • 12
  • 29
0

You have not included dependancy of _products in storeCtrl. When you call that service you get an error.

Correct code is:

angular.module("storeApp")
 .controller("storeCtrl", function($rootScope, $http, storeFactory, _products) {

   var products;

   storeFactory.getProducts().then(function(_products) {
     products = _products.data;
     $rootScope.products = products;
   });

You can use console.log("something here" + _products.data); to see in your browser console

Paul Roub
  • 36,322
  • 27
  • 84
  • 93