Laravel full URL routing - url-routing

How can I set my routes depending on the domain-name? I want to register some actions to diffenrent domain-names (not sub-domains).
Example of the functionality I need to replicate:
Route::any('www.domain1.com', 'Controler#Action1');
Route::any('www.domain2.com', 'Controler#Action2');
I can't use URL rewriting in .htaccess because I store domain->route maping in my database.

i think you can do it like this
Route::group(array('domain'=>'www.domain1.com'), function(){
Route::get('/',array('as'=>'domain1Home', 'uses'=>'Controller#Action1'));
});
Route::group(array('domain'=>'www.domain2.com'), function(){
Route::get('/',array('as'=>'domain2Home', 'uses'=>'Controller#Action2'));
});
you can know more about that from http://laravel.com/docs/routing#sub-domain-routing its some how the same way of thinking ..

Related

location.path() not redirecting to page

In node this is how I define my details route (render as jade and send).
app.get('/details', function(req, res){
jade.renderFile('details.jade', function(err, html){
if(err){
console.log(err);
}
res.send(html);
});
});
In jade with 'blah' is clicked then calls navigateToPath function with params.
a(ng-click="navigateToPath(date_obj_key, part)") blah
In angular, this function should go to this path. The url path changes in the browser but it does not REDIRECT to the page. Help (yes I am injecting the location service)
$scope.navigateToPath = function(date, part){
var path = '/details?date='+date+'&part_type='+part;
$location.path('/details').replace(); //also tried $location.url(path)
$scope.apply(); //also tried $scope.$apply and $rootScope.$apply as func
console.log($location.path());
}
I am using Fire Fox developer tools(F12) and put a break point on where I used $window.location in my project and looked at the values in $window.location and this what it shows:
It seems like this would work. for both a location in the same folder or sub-folder as well as going to a completely different web site.
$window.location = $window.location.origin + path
or
$window.location = <whatever website you want to go to>
In my case I was just using the $window.location to call a rest service to download a file that the user selected from a ui-grid while still staying on the same page. and this may have worked for me because my scenario is a bit different then what yours is I think. so all I had to do was
$window.location = "../../services" + "<path to my rest service>" + $scope.shortCode + "/" + $scope.wireInstSelectedRow.entity.fileName;
#shapiro I am not sure why this does not work
$location.path('/details').replace();
I tried the same thing originally in my project and based on the documentation: https://docs.angularjs.org/api/ng/service/$location It seems like that would work and what its supposed to be used for but what I noticed is it would put a '#' character in the url before it put the path I wanted it to take which was preventing it from going to that page. Anyhow for me it seems like as long as you are going to an html page that is in the same folder or sub-folder just doing
$window.location = <the path you want to go to>;
is a good solution... at least it did the trick for me. Hope this helps.

Is there a Laravel route link Angularjs/otherwise?

I'm new to Laravel. As I asked in title, is there any route declaration in Laravel like AngularJS(otherwise) ? For example, I'll define some routes and all other URI requests will redirect to a certain page/index page/ error page ?
Your question is a little unclear, but it sounds like you're looking for a catch all route.
According to the Laravel Snippets sites, if you add the following to the end of your app/routes.php, this should give you what you want.
Route::get('{slug?}', function(){
return 'Catch All';
})->where('slug', '.+');
You clearly didn't even try to Google this: laravel routes.
http://laravel.com/docs/4.2/routing
In your Laravel application, locate to app/routes.php
That's where your routes are kept. You can define them like so:
Route::get('/home', function() {
return View::make('pages.home');
});
Or to call a controller:
Route::get('/home', ['uses' => 'HomeController#index']);
You can call HTTP verbs as well, like so:
Route::post('/some/form', ['uses' => 'YourController#process']);
Please see here for more info: http://laravel.com/docs/4.2/routing

AngularJS best practice REST / CRUD

What is the best practice of doing CRUD operations via REST with AngularJS?
Specially what is the Angular-Way here. By this I mean the way using the least code and the most default angular settings to achive this.
I know $resource and it's default operations. Where I'm not sure is how to implement/name the endpoints and which controllers to use.
For this example I would like to implement a simple user-management system which creates / updates /deletes / lists users. Since I'm implementing the Server-Endpoints by myself I'm completely free in doing it in the most angular friendly way.
What I like as answer is something like:
Server-Endpoints:
GET /service/users -> array of users
GET /service/user/new -> return an empty user with default values which has no id
POST /service/user/new -> store a new user and create an id. return the saved user.
POST /service/user/:ID -> save an existing user. Return the saved user
DELETE /service/user/:ID -> delete an existing user
Angular-Services:
.factory( 'User', [ '$resource', function( $resource ){
return $resource( '/service/user/:userId', { userId: '#id' } )
[...]
}])
Routing:
.when( '/users', {
templateUrl: BASE + 'partials/user-list.html',
controller: 'UserListCtrl' } )
.when( '/user/new', {
templateUrl: BASE + 'partials/user-edit.html',
controller: 'UserNewCtrl' } )
.when( '/user/:userId', {
templateUrl: BASE + 'partials/user-edit.html',
controller: 'UserEditCtrl' } )
...
Controllers:
UserListCtrl:
$scope.data = User.get(...)
UserNewCtrl:
$scope.user = User.get( { userId: "new" } )
...
Note that I'm not interessted in opinion what is the best (tm) way to do this but I'd like to know what is the Angular intended way (which I think should produce the least code because it can use the most default).
EDIT:
I'm looking for the whole picture. What I would love would be an answer like e.g.: "You can do this using online 3 Endpoints [...], 2 routes [...] and 2 controllers [...] if you do it this way using that defaults ..."
There is no Angular prescribed way for what you are asking. It's up to you to determine the implementation detail.
Typically I only use two controllers and templates per resource:
ListController
FormController
The Form controller is used for both Edit and Create operations. Use the resolve option in your route definitions to pass in either User.get() or User.new() and a flag indicating if this is an edit or create operation. This flag can then be used inside your FormController to decide which save method to call. Here's a simple example:
.when( '/users', {
templateUrl: BASE + 'partials/user-list.html',
controller: 'UserListCtrl' } )
.when( '/user/new', {
templateUrl: BASE + 'partials/user-form.html',
resolve: {
data: ['User', function(User) { return User.new(); }],
operation: 'create'
}
controller: 'UserFormCtrl' } )
.when( '/user/:userId', {
templateUrl: BASE + 'partials/user-form.html',
resolve: {
data: ['User', '$route', function(User, $route) { return User.get($route.current.params.userId); }],
operation: 'edit'
}
controller: 'UserFormCtrl' } )
And your form controller:
app.controller('UserFormCtrl', ['$scope', 'data', 'operation', function($scope, data, operation){
$scope.data = data;
$scope.save = function() {
if (operation === 'edit') {
// Do you edit save stuff
} else {
// Do you create save stuff
}
}
}]);
You can go a step further and create a base list and form controller to move stuff like error handling, server-side validation notifications etc. In fact for the majority of CRUD operations you can even move the save logic to this base controller.
My research into a similar quest has lead me to this project "angular-schema-form" https://github.com/Textalk/angular-schema-form.
For this approach...
You make a JSON-Schema that describes your data. Then augment it with another little JSON-struct that describes a "form" (ie. view specific info that does not belong in the data schema) and it makes a UI (form) for you.
One cool advantage is that the Schema is also useful in validating the data (client and server side), so that is a bonus.
You have to figure out what events should fire off GET/POST/... back to your API. but that would be your preference, eg. Hit the API for every key stroke OR the classic [Submit] button POST back style OR something in between with a timed Auto Save.
To keep this idea going, I think that it is possible to use StrongLoop to make a quick API, which (again) uses your data's schema (augmented with some storage details) to define the API.
no <3 uses of that schema, see [http://json-schema.org/] which is central to this approach.
(read: no less than three :)
You maybe mixing things up. CRUD operations at API level are done using $resource and these may or may not map to UI.
So using $resouce if you define resource as
var r = $resource('/users/:id',null, {'update': { method:'PUT' }});
r.query() //does GET on /users and gets all users
r.get({id:1}) // does GET on /users/1 and gets a specific user
r.save(userObject) // does a POST to /users to save the user
r.update({ id:1 }, userObject) // Not defined by default but does PUT to /users/1 with user object.
As you see the API is resource full but is in no way linked to any UI view.
For view you can use the convention you have defined, but nothing specific is provided by Angular.
I think what you are looking for can be found in http://www.synthjs.com/
Easily create new RESTful API resources by just creating folders and
naming functions a certain way.
Return data or promises from these
functions and they'll be rendered to the client as JSON.
Throw an
error, and it'll be logged. If running in dev mode, the error will
also be returned to the client.
Preload angular model data on page load (saving an extra
roundtrip).
Preload html view on page load (saving another extra
roundtrip!)
A simplified project structure
where front-end code (angular code, html, css, bower packages, etc)
is in the 'front' folder and back-end code (node code and node
packages) are in the 'back' folder.
A command-line tool for
installing third party packages, using npm + bower, that auto-updates
manifest files.
Auto compilation of assets on request for dev, and
pre-compilation for prod (including minification and ngmin).
Auto-restarts the server when changes are detected.
Support for
various back-end and front-end templates to help get a new project
going quickly.

Router in backbone not handling route after initialization

I have multiple routers in my app, in general way it looks like this:
// Start backbone.js
if (!Backbone.History.started) {
Backbone.history.start({pushState: true, hashChange: false});
}
// Perform some RPC requests ...
// Depending on user role, received from the server should be created suitable router:
var router;
if (typeof app.user.role === 'manager') {
router = new routers.manager();
} else {
router = new routers.guest();
}
Problem is that after page is loaded and script is executed routers do not do. anything. They do not load route for current url automatically. So, i had to fix it this way (i am not sure that it is a right way):
routers.guest.initialize = routers.manager.initialize = function() {
var defaultRoute = 'default';
if (typeof this.routes[Backbone.history.fragment] !== 'undefined') {
this[this.routes[Backbone.history.fragment]]();
} else {
this.navigate(defaultRoute, true);
}
};
It is working fine, except one bug: when i use route with params, for example /reset-password-confirm/:code - it is unable to find in in routes property. I could write some more code to fix it, but i suppose that i am doing something wrong, if i have to write such things - as i understand router should handle routes just after it was created.
So, questions:
Why my router(s) does not handle routes for current url after it is being created? Perhaps i need to start backbone history later? (but this bug will happen again later then)
How it is possible to make routes with params like /user/:id work there?
Perhaps it is bad idea to re-create routers? Perhaps it is better to create all of them one time?
P.S. I've tried to create both routers and keep them, also i've trie to call backbone history start method after all routers were created.. but this didn't help :/
Assuming you route is declared as the following:
routes : {
'/user/:id' : 'user'
}
Your initialize code is not working because when you initialize your router with a url such as: /user/1234. Backbone.history.fragment will be /user/1234 (not /user/:id). Since the this.routes object doesn't have a key of /user/1234, your else clause calls the default route.
If you first instantiate your router then call Backbone.history.start(), you will be able to remove your router initialize code. When you navigate to a url as /user/1234 your router will match the /user/:id route and call the user function.
The following should work for you without adding your initialize code:
var router = (app.user.role === 'manager') ? new routers.manager()
: new routers.guest();
Backbone.history.start({pushState: true, hashChange: false});
Looking at the code, seems like you're starting the backbone history before initializing any routes. That's most likely not goning to work.
The correct way of doing this type of seperation is by creating all the routes based on the role received from the server and then start the backbone history. Here's an SO thread that talks about it with code samples as well : How to protect routes for different user groups

Whats the better way to identify the context path in Angular JS

I have my web application deployed to tomcat with an applicatio context.
For example my URL looks something like this.
http://localhost:8080/myapp
myapp - is the application context here.
Now in an Angular service if i want to call a webservice say getusers. My URL should be this /myapp/getusers. But I want to avoid hardcoding the application context as it might change from one deployment to other.
I have managed to figureout the contextpath from $window.location.pathname but it looks very stupid. Is there a betterway?
FYI I am using Spring MVC for restful services.
What I have done is declared a variable in the main jsp file. Then that variable will be available throughout the angular application.
<script type="text/javascript">
var _contextPath = "${pageContext.request.contextPath}";
</script>
This code should be written in header before including other JavaScript libraries.
I'm also using tomcat and Spring MVC. Using relative url in JavaScript will do the trick.
For doing this you just need to remove the / at the begining of REST url. so that your url starts from the current url in your browser.
replace $resource('/getusers') with $resource('getusers')
Inject the $location service to your controller.
var path = $location.path(); // will tell you the current path
path = path.substr(1).split('/'); // you still have to split to get the application context
// path() is also a setter
$location.path(path[0] + '/getusers');
// $location.path() === '/myapp/getusers'
// ------------------ \\
// Shorter way
$location.path($location.path() + '/getusers');
// $location.path() === '/myapp/getusers'
In Angular 2 (if using hashbang mode). Below code can be used to form the url.
document.location.href.substr(0, document.location.href.lastIndexOf("/#")) + "/getusers";
Inspired from the answer of #jarek-krochmalski
if you are using hashbang mode, with "#", you can do something like that:
$location.absUrl().substr(0, $location.absUrl().lastIndexOf("#")) + "/getusers"
For AngularJS $http service you are good to go with url : 'getusers', as follows:
$scope.postCall = function(obj) {
$http({
method : 'POST',
url : 'getusers',
dataType : 'json',
headers : {
'Content-Type' : 'application/json'
},
data : obj,
});
};
In general, you should use injection in your controller like the following:
angular.module("yourModule").controller("yourController", ["$scope", "yourService", "$location", function($scope, yourService, $location){
....
//here you can send the path value to your model.
yourService.setPath($location.path());
....
}]);

Resources