Stop Laravel from loading new URL and let angular handle it - angularjs

So, I have a single page angular app that is opened when I navigate to a URL. If I use the links, moving around within the app is fine - new URLs load just fine. However, if I enter a new URL in the browser URL window and hit enter, the back end framework - Laravel in my case - tries to resolve the URL.
How do I either
Intercept the URL change so that I can simple direct it to the appropriate state in the app
Tell Laravel to ignore the new URL and let the angular app handle it
Thanks

If I understand your question correctly, you don't want Laravel handles it because the routes is defined in javascript, not in server side. If that's the case, you can simply solve it by using wildcard.
Let's say in your laravel's routes you have this line to load your app, views, javascripts etc:
Route::get('/', 'PagesController#index');
You can use the wildcard modifier to ignore whatever url that has appended, and always serve your index view instead:
Route::get('/{any?}', 'PagesController#index')->where('any', '.*');
I'm not sure why it's not in the latest documentation, but you can find the docs at Laravel 5.2 doc regarding regular expression constraints

Related

Routing an user in a single page application using the adress bar

I have a backend using express to serve a static directory, to the path /, in which is contained a single page frontend. This backend also serves an API REST.
The frontend is built in React, and uses react-router to route the user from the different views of the web application.
If my react-router have two entries, let say /app and /config,
how can I redirect the client to that view of the application, if the user enters directly the URL in the web browser's address bar?
Right now, if I do that, Express gets the request and obviously returns a 404 message, as the single page is served to / path.
A simple way to resolve that is to always (even on 404s) send to user the index.html in your express route handlers.
See: https://stackoverflow.com/a/25499007/2624575
However, you need to take care of some things:
1) Your React Router code should start to handle 404s: https://stackoverflow.com/a/37491381/2624575
2) You need to handle correctly the path to your assets (icons, css, js, etc), otherwise you'll send the same index.html to those kind of resources (which will make your page render incorrectly)
3) Make sure that react-router is using browserHistory (the history that doesn't use hashes #), This way React will be able to render your routes correctly
Hope it helps!

Single page application using AngularJS

I am working at a SPA using Flask(with jinja) and AngularJS. Everything works fine, but when the application is in a given state and I try to refresh the page in browser, the server responds with 404 response: "error": "Not found". Is there a way to make this work in a proper way when trying to access a page of the SPA application through the URL?
This may depend on how your dev http server is setup:
It should be set to always load the default page which is index.html such that the angular engine will load and run and only then it will serve the other routes (states) like localhost/state, otherwise the angular router would not be able to resolve the url since it is not loaded (letting the http server handle the request, serving a 404 Page Not Found)
The http servers sometimes serve only one level deep url's like localhost/state, not localhost/state/param and you need to change some settings to make it work, but I think this is beyond the scope of your question :)
You can use a hasher in SPA. You need to parse hash string before initializing view model and based upon the value of hash set your current visible page and then bind the view mode.
You need to have a rule to always return your SPA index.html page for any routes that match your angular routes. I'm not sure what your web server is, apache or nginx or whatever but you should be able to find instructions on how to match those requests back to index.html.
You must have enabled html5 mode to true in in your angular js app. Set that to false will solve your problem.

Issues in removing # from angular routes

I was trying to preetify my URL in angular js app and remove the hash. What I did was added in line in my app.config function:
$locationProvider.html5Mode(true);
But this issues I am still facing are:
If I open a page like this $window.location.href = '#/sales'; the slash is encoded and page does not opens.
If I directly type in my browser localhost:9000/sales without hash the page does not opens.
Can someone please help.
To add to it, my base url is: http://localhost:9000
You should choose just one option: either you have hashes in the url, or not.
If hashes are ok - then just remove $locationProvider.html5Mode(true); from your code.
If you really want your app to work w/o hashes in the url then follow this (probably incomplete) checklist:
Remove # from any urls on your page
Configure your web-server to feed the same webapp on all requests which your webapp recognizes. I.e. If your webapp routing knows what to do when user agent is requesting /sales - then make sure that your web-server or backend platform you are using serves the page with your web-app

Removing the hashtag from AngularJS when working with SailsJS

I'm getting really frustrated with configuring the Routing on our app, which is using sailsJS and angularJS.
The problem is, that the browser doesn't know about angular, so any request like /login returns a 404 Error from sails. I need a solution, to keep the sails routes from the angular ones,
One solution would be to disable html5Mode, but i really don't like the look of URLs with the /#/ which is typical for angular.
I have researched a lot on this and haven't yet found a good answer or maybe a working project for this.
Is what I am trying to do even possible right now?
If you're using HTML5 mode with Angular, then you need to configure your web server (in this case SailsJS) to respond with your index.html file for requests to /login or any arbitrary routes.
If you navigate directly to http://localhost:3000/login in your web browser (assuming you're running Sails on localhost:3000), Sails needs to respond with your index.html so that your Angular app can bootstrap and then display the appropriate route. Then, subsequent links that the user clicks on in your app will be intercepted directly by the Angular router instead of Sails directly.
Angular has documentation about making HTML5 mode work correctly here.
Using this mode requires URL rewriting on server side, basically you have to rewrite all your links to entry point of your application (e.g. index.html). Requiring a <base> tag is also important for this case, as it allows Angular to differentiate between the part of the url that is the application base and the path that should be handeled by the application.

How to handle non-root URLs in a singlepage app?

I try to make a single page app with Rails 3.2 and Backbone.js with pushState option but faced with something that I do not understand.
If I load the root URL of the app (/), everything goes right: Rails return an HTML-layout with JS which bootstraps Backbone which makes some XHRs for JSON-entities and renders the content.
But if I start using app from non-root URL (e.g. by manually typing it in the browser's address bar) then Rails will try to handle this request using theirs routing rules from routes.rb - that's wrong, cause it's a "Backbone's" route. How do I load the page and bootstrap Backbone for handling this URL in that case?
Finally I found the solution.
I put the following code into my routes.rb
class XHRConstraint
def matches?(request)
!request.xhr? && !(request.url =~ /\.json$/ && ::Rails.env == 'development')
end
end
match '(*url)' => 'home#index', :constraints => XHRConstraint.new
With this matcher all non-XHR requests are routed to HomeController which returns an HTML page. And XHR requests will be handled by other controllers which return JSON responses.
Also I left requests ending with ".json" as valid in development environment for debugging.
This is a somewhat tricky issue, but basically in a nutshell, you need to respond to all valid (HTML) requests in rails with the same (root) page, from there backbone will take over and route to the correct route handler (in your bakckbone router).
I've discussed this issue in more detail here: rails and backbone working together
Basically what I do is to create actions for every page that I want to handle, and blank views. I use respond_with to return the page (which is the same in each case) and because I handle GET actions only for HTML requests, I add this line at the top of the controller:
respond_to :html, :only => [ :show, :new ]
JSON requests are handled with respond_with as well, but unlike the HTML requests actually return the requested resource (and perform the requested action in the case of PUT, POST and DELETE).
Backbone will not be informed of your url change if you do it manually. This change will be catch by the browser and it will do its job sending the request to the server as usual.
Same if you click in a normal link, it will follow its href without inform Backbone.
If you want Backbone being in charge of a url change you have to do it through the Backbone tools you have available and this is the own Router.
So if you want to make an URL change in the Backbone way you have to do it explicitly, something like:
app.router.navigate("my/route", {trigger: true});

Resources