Cannot access Angular scope variable from pug/HTML (yeoman angular-fullstack) - angularjs

I cannot access from PUG to a variable in the controller. Please, may anybody help me?
I´m trying to access the AwesomeThings array with $ctrl.awesomeThings,
with JavaController.awesomeThings, with this.awesomeThings, with java.awesomeThings, and none
of them seem to work. The ng-repeat never creates nor an option. It seems
that the array is not being recognized.
Could you please help me guys? I´m sure i´m missing something that I do not know of the new versions of angular-fullstack + Typescript.
Thanks a lot.
The PUG file
.container
p
| Documentación Java
hr
ul.nav.nav-tabs.nav-stacked.col-md-4.col-lg-4.col-sm-6
li(ng-repeat='thing in awesomeThings') //THIS IS WHAT DOES NOT WORK
a(ng-href='{{thing.URL}}', uib-tooltip='{{thing.nombre}}', target="_blank") {{thing.nombre}}
The Controller
'use strict';
export default class JavaController {
awesomeThings = [{nombre:"La tecnología Java", URL: "http://www.ciberaula.com/articulo/tecnologia_java"},
{nombre:"La Programación orientada a Objetos (VIDEO)", URL: "https://www.youtube.com/watch?v=8UgQNQML_b8"},
{nombre:"Herencia y relaciones entre objetos", URL: "https://www.arquitecturajava.com/herencia-y-el-principio-de-substitucion-de-liskov/"},
{nombre:"Herencia en Java", URL: "https://jarroba.com/herencia-en-la-programacion-orientada-a-objetos-ejemplo-en-java/"},
{nombre:"Java, overrides y encapsulación", URL: "https://www.arquitecturajava.com/java-override-y-encapsulacion/"},
{nombre:"Artuitectura de componentes y JEE (PDF)", URL: "http://ocw.uc3m.es/ingenieria-telematica/software-de-comunicaciones/transparencias/3_cmpnts-JavaEE.pdf"},
{nombre:"Clases y medotodos", URL: "https://www.aprenderaprogramar.com/index.php?option=com_content&view=article&id=426:ique-es-una-clase-java-concepto-atributos-propiedades-o-campos-constructor-y-metodos-cu00623b&catid=68&Itemid=188"},
{nombre:"Glosario de conceptos", URL: "https://www.java.com/es/download/faq/helpful_concepts.xml"},
{nombre:"Arquitecturas MVC/REST", URL: "https://www.youtube.com/watch?v=qyt2Ct0hWqU"},
{nombre:"POJO, DTO, JavaBeans", URL: "https://www.youtube.com/watch?v=Iy7je1tJ20Y"},
{nombre:"CURSO JAVA DESDE CERO (lista de videos)", URL: "https://www.youtube.com/playlist?list=PLU8oAlHdN5BktAXdEVCLUYzvDyqRQJ2lk"},
{nombre:"MAVEN, Qué es", URL: "http://www.javiergarzas.com/2014/06/maven-en-10-min.html"},
{nombre:"Qué es JUnit", URL: "https://mikiorbe.wordpress.com/2009/10/23/junit-herramienta-indispensable-para-el-desarrollo-java"},
{nombre:"Qué es JavaDocs", URL: "http://java-white-box.blogspot.com.es/2012/08/javadoc-que-es-el-javadoc-como-utilizar.html"},
{nombre:"Arquitectura Java - Básico (VIDEO)", URL: "http://java-white-box.blogspot.com.es/2012/08/javadoc-que-es-el-javadoc-como-utilizar.html"},
{nombre:"Arquitectura Java - La máquina virtual Java", URL: "https://cursos.arquitecturajava.com/courses/programacion-orientada-a-objeto-en-java/lectures/2857884http://cursos.arquitecturajava.com/courses/programacion-orientada-a-objeto-en-java/lectures/2857884"},
{nombre:"Arquitectura Java - Clases y objetos", URL: "https://cursos.arquitecturajava.com/courses/programacion-orientada-a-objeto-en-java/lectures/2863618"}
];
/*#ngInject*/
constructor() {
console.log(this.awesomeThings);
}
}
The Index.ts for my controller
'use strict';
const angular = require('angular');
import routes from './java.routes';
import JavaController from './java.controller';
export default angular.module('homeCalidadApp.java', [
'homeCalidadApp.auth',
'ui.router'
])
.config(routes)
.controller('JavaController', JavaController)
.name;

After some research, I finally found what was the trouble and the solution:
The controller must be identified by controllerAs method. Then, after
identifying the controllerAs name, you will be able to access to it.
If you use, for example, controllerAs("pp"), the value in the pug file will be {{pp.value}}
Here is the link with the info. Check #jasonals comment on 12 Oct
2013
The PUG file:
.container
p
| Documentación Java
hr
ul.nav.nav-tabs.nav-stacked.col-md-4.col-lg-4.col-sm-6
li(ng-repeat='thing in ctrl.awesomeThings') //CHECK HERE. The right value is CTRL.awesomeThings
a( ng-href='{{thing.URL}}', uib-tooltip='{{thing.nombre}}', target="_blank") {{thing.nombre}}
The route
export default function routes($stateProvider) {
'ngInject';
$stateProvider
.state('java', {
url: '/java',
template: require('./java.pug'),
controller: 'JavaController as ctrl'
});
};
The Controller
export default class JavaController {
$http;
awesomeThings = [{nombre:"La tecnología Java", URL: "http://www.ciberaula.com/articulo/tecnologia_java"},
{nombre:"La Programación orientada a Objetos (VIDEO)", URL: "https://www.youtube.com/watch?v=8UgQNQML_b8"},
{nombre:"Herencia y relaciones entre objetos", URL: "https://www.arquitecturajava.com/herencia-y-el-principio-de-substitucion-de-liskov/"},
{nombre:"Herencia en Java", URL: "https://jarroba.com/herencia-en-la-programacion-orientada-a-objetos-ejemplo-en-java/"},
{nombre:"Java, overrides y encapsulación", URL: "https://www.arquitecturajava.com/java-override-y-encapsulacion/"},
{nombre:"Artuitectura de componentes y JEE (PDF)", URL: "http://ocw.uc3m.es/ingenieria-telematica/software-de-comunicaciones/transparencias/3_cmpnts-JavaEE.pdf"},
{nombre:"Clases y medotodos", URL: "https://www.aprenderaprogramar.com/index.php?option=com_content&view=article&id=426:ique-es-una-clase-java-concepto-atributos-propiedades-o-campos-constructor-y-metodos-cu00623b&catid=68&Itemid=188"},
{nombre:"Glosario de conceptos", URL: "https://www.java.com/es/download/faq/helpful_concepts.xml"},
{nombre:"Arquitecturas MVC/REST", URL: "https://www.youtube.com/watch?v=qyt2Ct0hWqU"},
{nombre:"POJO, DTO, JavaBeans", URL: "https://www.youtube.com/watch?v=Iy7je1tJ20Y"},
{nombre:"CURSO JAVA DESDE CERO (lista de videos)", URL: "https://www.youtube.com/playlist?list=PLU8oAlHdN5BktAXdEVCLUYzvDyqRQJ2lk"},
{nombre:"MAVEN, Qué es", URL: "http://www.javiergarzas.com/2014/06/maven-en-10-min.html"},
{nombre:"Qué es JUnit", URL: "https://mikiorbe.wordpress.com/2009/10/23/junit-herramienta-indispensable-para-el-desarrollo-java"},
{nombre:"Qué es JavaDocs", URL: "http://java-white-box.blogspot.com.es/2012/08/javadoc-que-es-el-javadoc-como-utilizar.html"},
{nombre:"Arquitectura Java - Básico (VIDEO)", URL: "http://java-white-box.blogspot.com.es/2012/08/javadoc-que-es-el-javadoc-como-utilizar.html"},
{nombre:"Arquitectura Java - La máquina virtual Java", URL: "https://cursos.arquitecturajava.com/courses/programacion-orientada-a-objeto-en-java/lectures/2857884http://cursos.arquitecturajava.com/courses/programacion-orientada-a-objeto-en-java/lectures/2857884"},
{nombre:"Arquitectura Java - Clases y objetos", URL: "https://cursos.arquitecturajava.com/courses/programacion-orientada-a-objeto-en-java/lectures/2863618"}
];
/*#ngInject*/
constructor($http, $scope, socket) {
this.$http = $http;
//this.socket = socket;
$scope.awesomeThings = this.awesomeThings;
}
}

Related

ui-router - How to load url without $stateParams on refresh?

My oversimplified app.config() has:
$stateProvider.
state("/", {
url: "/",
templateUrl: "main.html"
}).
state("/newCategories", {
url: "/categories/new",
templateUrl: "/views/new_categories.html",
controller: "newCategoriesCtrl"
}).
state("/categoryPages", {
url: "/categories/:address",
templateUrl: "/views/categories.html",
controller: "categoriesCtrl",
resolve: {
categoriesDataResolve: function resolveTemplate($stateParams, DataResolver) {
return DataResolver.resolveTemplates($stateParams.address);
}
}
});
With this I can use ui-serf link with "/newCategories" to load its url: "/categories/new"
<a ui-sref="/newCategories">New Category</a>
However, when I refresh, it thinks that "/new" is part of $stateParams. Therefore it uses a different controller and tries to resolve its template (which is missing, so it gives an error).
For now I fixed it by changing the url from "/categories/new" to "/categories-new" so it won't get confused on refresh. But how do I solve this issue differently? (Maybe ui-router has a some way of dealing with it)
If I understand you right, you want to call different controller a.e. newCategoriesCtrl when user calls /categories/:address where address param is new
Changing /categories/new to "/categories-new is a right way to solve it.
Small tip: its not good practice to use / as prefix for state name. It confuses the developer and can be mixed with original URL.
$stateProvider.
//...
state("newCategories", {
url: "/categories-new",
templateUrl: "/views/new_categories.html",
controller: "newCategoriesCtrl"
}).
state("categoryPages", {
url: "/categories/:address",
templateUrl: "/views/categories.html",
controller: "categoriesCtrl",
resolve: {
//...
}
});

angular ui-router for dynamic page url

I have an angular app where I am using ui-router module. I am storing a "page" in database with URL and content. I also have some other states/URLs that have their own template. For example:
$stateProvider
.state('landing', {
url: '/',
templateUrl: 'landing-page.html'
})
.state('admin', {
url: '/admin',
templateUrl: 'admin.html'
})
.state('user', {
url: '/user',
templateUrl: 'user.html'
})
I want to define a state for the pages using something like
.state('page',{
url: '??',
templateUrl: 'page.html'
})
What should be in the url above if my page is dynamically stored in database with a URL/slug and content. How can I add the URL/slug here ? If I try this below:
.state('page', {
url: '/{path:.*}',
templateUrl: 'page.html'
})
Then it routes every page including the other states to the same template. I can always prefix the URL with something like /page but I don't want to do that. I want to be able to load the page as :
www.mysite.com/page-1
www.mysite.com/whatever-url
etc
Never mind. I figured this out. The trick was more about using regular expression. Here is my solution
.state('page', {
url: '/{path:(?!admin|user)[a-z0-9\-]+}',
templateUrl: 'page.html'
})
This will ignore routes starting with /admin and /user which we want first. Then, it will check if the url has at least 1 character.

Angularjs and dynamic routes

I am trying to create a link in my template angularjs by doing something like:
<a ng-href="/#!/content/[[value.id]]">[[key]]</a>
But I am wondering myself if is possible do something like symfony2 does, example:
routing.yml
home_redirect:
path: /
defaults:
_controller: FrontendBundle:Controller:function
path: /home
permanent: true
options:
expose: true
And using it in your twig template by doing:
one link to home
That is really, really helpful because I don't have to "hardcode" all my routes.
To ensure a proper routing, you can use ui-router.
Here is an exemple on plunker
How this works :
1 - Follow the installation guide on their github
2 - Write your state definition :
app.config(function($stateProvider, $urlRouterProvider){
//If no route match, you'll go to /index
$urlRouterProvider.otherwise('/index');
//my index state
$stateProvider
.state('index', {
url: '/index',
templateUrl: 'index2.html',
controller: 'IndexCtrl'
})
//the variable state depending on an url element
.state('hello', {
//you will be able to get name with $stateParams.name
url: '/hello/:name',
templateUrl: 'hello.html',
controller: 'HelloCtrl'
})
});
3 - Write links by their state name :
//add this directive to an html element
//This will go to /index
ui-sref="index"
//This will go to /hello/
ui-sref="hello"
//This will go to /hello/ben
ui-sref="hello({name:'ben'})"
//This will go to /hello/{myname}
ui-sref="hello({name:myname})"
4 - Get the param into your controller :
//inject $stateParams
app.controller('HelloCtrl', function($scope, $stateParams){
$scope.controller = "IndexCtrl";
//get the param name like this
$scope.name = $stateParams.name;
});
Hope it helped. Also keep in mind the ui-router got some really powerful tools such as resolve and nested state/view. You'll probably need theses now or later.
PS : If the plunker don't work, just fork it and save again.
You could do this :
'use strict';
angular.module('AngularModule')
.config(function ($stateProvider) {
$stateProvider
.state('YourStateName', {
url: '/your/url',
views: {
'aViewName': {
templateUrl:'views/components/templates/yourTemplate.html',
controller: 'YourController'
}
},
resolve: {
}
});
});
// then in your controller
angular.module('AngularModule')
.controller('MyController',function($scope, $state){
$scope.goTo = function(){
$state.go('YourStateName');
}
}
);
//in your html make sure the <a> tag is in scope with the 'MyController'
<a ng-click='goTo'>[[key]]</a>
or
you can just do this :
<a ng-href="/your/url"></a>
that way you bypass the controller you can still put logic in the controller that was specified in the state

AngularJs UI router - one state with multiple URLs

I have a request to add in another URL parameter that directs to a state that I already have set up. For efficiency purposes, I'm trying to see if I can add multiple URLs to point to the same state, or should I just use the $UrlRouterProvider.when() method to re-direct to that state in this new case.
Ex. this is what already exists
.state('site.link1',
{
url: '/link1',
templateUrl: '/views/link1.html',
controller: 'link1Ctrl'
})
and the request is to add www.site.com/newlink that points to the link1 page. Is there something like this;
.state('site.link1',
{
url: '/link1, /newlink',
...
Try using the Regex and a parameter in the url. It is not optimal but works.
.state('site.link1',
{
url: '/{path:link1|newlink}',
templateUrl: '/views/link1.html',
controller: 'link1Ctrl'
})
More information on regex in Urls.
To generate links with ui-sref pass the same parameter with the state name as a function
<a ui-sref="site.link1({path:'link1'})" >site link 1</a>
<a ui-sref="site.link1({path:'newlink'})">site new link</a>
You use params:
https://github.com/angular-ui/ui-router/wiki/URL-Routing
.state('site.link',
{
url: '/{link}'
..
}
so when you use the same state like this
$state.go('site.link', {link: 'link1'})
$state.go('site.link', {link: 'link2'})
you can used when() function
.state('site.link1',
{
url: '/link1',
templateUrl: '/views/link1.html',
controller: 'link1Ctrl'
})
then on root config
angular.module('myApp', [...])
.config(function ($urlRouterProvider) {
$urlRouterProvider.when(/newlink/, ['$state','$match', function ($state, $match) {
$state.go('site.link1');
}]);
});
I found this approach to be quite simple and clean: create two equal states, just changing the url property
//Both root and login are the same, but with different url's.
var rootConfig = {
url: '/',
templateUrl:'html/authentication/login.html',
controller: 'authCtrl',
data: {
requireLogin: false
}
}
var loginConfig = Object.create(rootConfig)
loginConfig.url = '/login'
$stateProvider
.state('root', rootConfig)
.state('login', loginConfig)
I had almost the same problem, only with another constraint - I didn't want to use a redirect, since I wanted the url in the browser to stay the same, but display the same state.
This was because I wanted the chrome saved passwords to work for users that already saved the previous url.
In my case I wanted these two urls :
/gilly and
/new/gilly
to both point to the same state.
I solved this by having one state defined for /gilly, and for the second url, I defined an abstract state called /new.
This should be set up like this :
$stateProvider.state('new', {
abstract: true,
url: '/new'
template: '',
controller: function() { }
}).state('gilly', {
url: '/gilly',
template: 'gilly.html',
controller: 'GillyController'
}).state('new.gilly', {
url: '/gilly', // don't add the '/new' prefix here!
template: 'gilly.html',
controller: 'GillyController'
});

AngularJS transition to abstract state

I'm working on an application built with AngularJS that has two different states:
App intro wizard
App pages (with a Navigation template and nested views)
I want to default to State 1 the first time someone access the app, once done the wizard, continue on to the App pages, State 2.
My "app" state (State 2) is an abstract state because it has nested views. So I cannot transition to this state.
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('intro', {
url: '/',
templateUrl: 'templates/intro.html',
controller: 'IntroCtrl'
})
.state('app', {
url: '/app',
abstract: true,
templateUrl: 'templates/menu.html',
controller: 'AppCtrl'
})
.state('app.playlists', {
url: "/playlists",
views: {
'menuContent' :{
templateUrl: "templates/playlists.html",
controller: 'PlaylistsCtrl'
}
}
});
$urlRouterProvider.otherwise("/");
})
I've got the same problem as you, here is a post about abstract state: angularjs ui-router default child state and ui-sref
It explains why you can't directly access abstract state
Hope it helps.
I have added $location service to the controller of the "intro" page and use the following to transit to app state which works for me.
$location.path('app/playlists');
The menu.html is loaded and navigated to playlists.
In a service:
$location.path(
$state.href('app.some.abstract.state', { some: 'params' })
);
Or in a template ($state must be available in the local or global $scope):
<a ng-href="{{$state.href('app.some.abstract.state', { some: 'params' })}}">...</a>

Resources