AngularJS: Best practices for routes and controllers - angularjs

on our company, we're currently working on a single page web application. Users can login and fill their profiles with data and share those with other subscribers (it's a social network-ish application).
Now, I've imagined this schema:
the users data are provided by a UserService, using REST APIs to recover profiles information;
the profiles related pages are managed by a unique controller (ProfileController);
my question is: what's the best way to associate a route (let's say "view-profile") to a specific controller method (ProfileController.viewProfile)? Is this a right pattern in AngularJS?
Thanks!

Investigating further I've found that the best way to achieve the result I want is by using the resolve in the state configuration, as explained in this article: https://scotch.io/tutorials/making-skinny-angularjs-controllers.
EDIT:
I'll try to explain it a little bit. What I'm trying to achieve is to route a specific application state to a controller method, in order to avoid preloading a huge subset of data everytime I access the controller. Let's say I've this situation in my ui-router
.state('view-profile', {
url: '/view-profile',
templateUrl: 'components/profile/profile.html',
controller: 'ProfileController'
})
[...]
.state('edit-profile', {
url: '/edit-profile',
templateUrl: 'components/profile/edit-profile.html',
controller: 'ProfileController'
})
Since the ProfileController could potentially do a lot of stuff, not necessary related to edit/view, I'd like to set a specific controller method to be called when I navigate to these urls.
In other MVC frameworks you can associate a route to a specific controller method, so you'll have
route: /edit-profile -> resolvesAs: ProfileController.editProfile(args)
Unfortunately, there's no really a way to do this in AngularJS 1.4, at least not using the ui-router.
But fortunately enough, we can use the resolve attribute on the ui-router configuration to avoid preloading useless data for a specific route.

Related

SaaS app with angularjs and nodejs, how do i organize different clients?

I’m trying to decide what to do I this scenario:
I want to create a product that I want to sell in a SaaS business model, I already have the backend more or less thought out and some code in place in nodejs. It handles oAuth, sessions, and controls the roles of the users when accessing a certain endpoint.
The doubt is in the frontend architecture:
Each client will share the same functionality, but the design of their page will be completely different from one another.
I want to put as much of the app logic that I can in services, so I can reuse it, my idea is to only change controllers/templates/directives from client to client, is this ok?
Should I have different folders and serve the static files for each client from nodejs?
ex:
in nodejs I would know the url for client1 was called so I would serve client1-index.html?
should I put each client in their own nodejs server and their own host?
what other ways are there?
I would like to be able to easily reuse the services as I’ll be introducing changes to the features or adding more, and I want to do this upgrades easily.
There will also be an admin panel that will be exactly the same for all of them, the part that will change is the one my client's users see.
Think of it as having many clients and giving each of them a store, so they can sell their stuff. They want an admin page and a public page. The admin page will the same for all, but the public page has to change.
So, and app that shares the same functionality across users but looks completely different for each one of them, how would you do it?
Since You seem to be using Angular, have you thought of using the routing service? See more about it Here : https://docs.angularjs.org/api/ngRoute/provider/$routeProvider
Basically what it does is it based on the url loads a html page and a controller (JS file). For example if your user would just be move to url.com/client1 and angular would load client1.html and client1CTRL.
A Simple Structure would be the following:
Index.Html- References to any dependencies, and in the body only a ng-view tag
Templates (The Html Templates for each of the users)
Login
Admin
Client 1 etc...
Scripts (JS)
External Scripts (Jquery, Angular ETC)
Index.js ( This is where you would have all your js controllers for each page)
Stylesheets
CSS FILES GO HERE
Example Angular Routing: Tutorial
var App = angular.module('saasApp', []);
App.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/admin', {
templateUrl: 'templates/admin.html',
controller: 'AdminController'
}).
when('/client1', {
templateUrl: 'templates/client1.html',
controller: 'client1Controller'
}).
when('/login', {
templateUrl: 'templates/login.html',
controller: 'loginController'
}).
otherwise({
redirectTo: '/login'
});
}]);
Hope this works for what you are trying to do.
I guess your question is about Architecture. If I were to do same back-end and different front ends I would've implemented virtual template structure.
Permissions
I would have:
a super user that has rights to setup multiple stores.
an admin user that can manage a particular store
Super User template management.
I would have base templates in /admin/templates and when I create a new store I would copy them and stick them in database
I would create a menu with all the templates on the left hand side and have wysiwyg editor that allows me to modify those template for particular customer and upload additional assets (images, pdfs etc)
Template would support swig syntax
I would create a server route /get/tempalte/:id and dynamically parse those templates on server using swig engine
I hope this helps. The key here is to be able to update templates via browser and distribute them to new shops/customers via web panel.

How i can maintain angular-fullstack client and admin different template

I want to use different different types of template in client side and admin side using angular-fullstack.
Can you please let us know how i can achieve this. My routes look like Ex:
www.sitename.com - main site with theme1 (http://demo2.jlvextension.com/probusiness/)
www.sitename.com/administrator - administrator dashboard with theme2 (http://www.theme-guys.com/materialism/angular/)
It seems to me like you're trying to create two very different front ends. I recommend building two different angular applications that utilize the same api's and domain. You could put an entire admin angular application at www.[sitename]/admin.
We also had a requirement like this and initially we had both in one SPA, where we distinguished each page by URL. The URL 'admin/login' loaded admin login page while '/login' loaded the login page for others. The $routeProvider config is given below.
$routeProvider.when("/admin/login", {
templateUrl: "app/admin/login.html",
controller: "AdminCtrl"
}).
when("/login", {
templateUrl: "app/user/login.html",
controller: "LoginCtrl"
}).
Later when the application became big and difficult to maintain, we ported the admin part to a separate application like Gabriel suggested above.
you can resolve this problem with creating a directive with different
templates,This plunker should demonstrate what needs to be done,
but basically:(you should just change the value of isAdmin property
to simulate ). good luck

Creating Separate UI for different Roles

I have two roles in my application say Customer and Provider and I want to create separate UI for them after they are authenticated, keeping login screen same and have a radio button that says "I'm a Customer" and "I'm a Provider", this also be same during registration.
I'm looking for a better approach, I have no Idea how to start with.
I already have a an existing UI interface for customers, but now requirement is for "Provider" Interface. So that customer can interact , send requirements, do query directly with provider. currently Customer application send these request by email.
First of all you should detect and define which components are going to be shown for both and which components are only for one or other. After you know exactly how your app will be, angularjs provides a lot of native directives for managing different cases.
Take a look at:
ng-if
ng-switch
ng-hide
ng-show
Those will be of great help for you. But always remember to manage security server side, web apps can be easily manipulated and if you are working with roles and different permissions take this as a must have.
BTW, consider using angularjs $routeProvider in some of the following ways for managing permissions:
$routeProvider.when('/admin/users', {
controller: 'userListCtrl',
templateUrl: 'js/modules/admin/html/users.tmpl.html',
access: {
requiresLogin: true,
requiredPermissions: ['Admin', 'UserManager'],
permissionType: 'AtLeastOne'
});
OR
$routeProvider.
when('/admin', {
templateUrl: 'Your template url',
controller: 'AdminController',
permission: 'AccessAdministration',
resolve: {
permissionList: function (permissionService) { return permissionService.getPermissions(); }
}
})

Autonomous routing on AngularJS

I am working on a project with more 300+ pages based on AngularJS.
Everything is all right, but I'd like to find a way to get rid of those 300+ lines for routing.
Here my thoughts :
User goes on url /settings/company
AngularJS has to load templateUrl at '/template/'+settings/company+'.html'
Then AnguarJS loads controller SettingsCompany+'Ctrl'
Do you think if it is possible ?
If you are using ui-router which I would recommend you can create your routes Dynamicly all you need to do is
var state = {
url: someUrl
template: someHtml
controller: someController
};
$stateProviderRef.state(TheStatename, state);
You obviously need to do that before loading the view. I personally have a static login in my app and after i know which user logged in i load different modules and with this i basicly create the states dynamicly and load the Controller files with lazyload.
Hope this was helpful

Using UIRouter templates with MVC 4 Routing

I'm trying to create an ASP MVC 4 project with Ui-Router, however I've come across a problem.
My current server-side routing configuration looks like this:
// Controller/Action route
routes.MapRoute(
name: "Default",
url: "{controller}/{action}");
// Redirect any other routes to Site/Index so AngularJS can handle routing
// Place routes above this otherwise they will be ignored
routes.MapRoute(
name: "Catch-All Redirect to Index",
url: "{*url}",
defaults: new { controller = "Site", action = "Index" }
);
And client-side
angular.module('loluk.home')
.config(['$stateProvider', function ($stateProvider) {
$stateProvider.state('index', {
url: '',
templateUrl: '/home/index'
});
}]);
Site/Index, the redirect action, simply contains the HTML file that has the ng-app directive. Any other actions/controllers will return API data, or a template. So, in my case, I have Home/Index which returns a template containing <h1>Hello, World!</h1>.
This is all fine and dandy if one of my states in ui-router requests "home/index" via templateUrl for my application. However, the problem I have now is that if I browse to http://localhost/Home/Index, I will see the template in it's raw form - rather than what I am expecting to see, which is the whole application in the Home/Index state. This makes sense as that is how I have configured it.
I initially thought "OK, well I can solve this problem by redirecting everyone to Site/Index (where the main file is stored) and using inline templates". Well, this works well, until you consider that
The HTML file containing index.html is going to get ridiculously large and contain every template
This breaks escaped_fragment crawling
So right now I am at a loss of how to make this work; I could use inlining, but that would make web pages load slowly and break SEO. I could stick with what I have.. but that will break any bookmarks that end-users create.
Making template calls a ChildActionOnly worked well until the fact that ChildActionOnly will return a server 500 (rather than a redirect), and UI-Router appears to not qualify as a "Child Action" as requesting the template through templateUrl also triggered the server 500.
I did come across this question, however it doesn't express how exactly to solve the template situation.
Another avenue I have just pursued is having a templates area that contains all of my templates, and an api area that contains all of my api details (/templates/ and /api/ respectively). This solves the whole reloading page problem, though I am still unsure of how to approach the escaped_fragment crawling from this point of view.
I've accomplished this by creating two Areas in MVC - one for API that routes to /api/ and one for Templates that routes to /templates/. AngularJS will make calls to /template/{controller}/{action} which will return a plain HTML view, and make RESTful calls to /api/{controller} for retrieving data.
It's not a perfect solution but it works.

Resources