I have an AngularJS application which has multiple apps. I've broken apart the single-page paradigm to 1) get server-side SEO urls and 2) to keep each app more modular.
I'd like to perform an in-page refresh IF the current app includes the route I'd like to go to. However, if the new route crosses between apps, I'd like to do an "absolute" redirect. I don't like the idea of configuring all possible routes, to test if an app is "crossed boundaries".
One solution I've been researching is testing the router to see if a route exists. If it doesn't then do an absolute redirect.
Is this a good solution, and if so - how to inspect the existing routes? I suspect this happens a lot with Express/NodeJS apps.
I am using ngRoute module.
Thanks!
I found this: check $route.routes for existence of route. If missing, do an absolute redirect, otherwise do an in-page ($location.path()).
(One) solution looks like this.
this.ChangePathAcrossApps = function(newpage) {
if ($route.routes[newpage]) {
$location.path(newpage);
} else {
document.location = '/#' + newpage;
}
}
Related
I am completely new to Laravel + AngularJs. What I want to do is handle my web.php routes using AngularJs. Is it possible? If it how can I do that?
If you have an SPA and your app is using HTML5 history mode, this should be similar to how people often combine Laravel and VueJS routing.
You'd usually have all of your non-Angular routes at the top of routes/web.php and then a "catch-all" route for your SPA. This "catch-all" route is basically a route that doesn't care what the route looks like; it will just send it on to the AngularJS app.
Similar to this answer or this article your routes/web.php might look something like:
Route::resource('Videos', 'VideoController')->middleware('auth','isAdmin');
Route::resource('Categories', 'CategoriesController')->middleware('auth');
...
Route::get('/{angularjs_capture?}', function () {
return view('angularjs.index');
})->where('angularjs_capture', '[\/\w\.-]*');
And then you'd have a view at /resources/views/angularjs/index.blade.php that contains the base HTML for your SPA.
Is there a way to keep track of history outside of a backbone router. I have a pagination service provided by Laravel, the links between pages are like the following "#leads?page=7". Everything works, but I have no clue right now on how to apply track of history outside of the router. The router works for the dashboard options but not for the pagination.
I am not using Backbone.Marionette for a single page app, but more for varius tools on my site. I wanted to have Laravel render the initial pages for SEO reasons. I had Laravel write the first pagination block then I have Marionette rewrite it after any interaction. You have to love twice the amount of work, but I like the fact that I don't have to worry about search engine not seeing the page.
In order to do this, I ended up not using the backbone router for this tool at all. I used javascript history. It is only available in newish browsers, but that is what our site supports. If you do need to support older browsers there is a shim, but I have not used it.
// add to history
history.pushState('', 'Search: ' + tags, url);
// get current history
updateUrl: function(){
var currentState = history.state;
return (currentState) ? currentState : $(this)[0].baseURI;
}
It definitely was more work, but I was able to get it working the way I wanted.
I was setting up a simple router in Backbone.js while I noted an issue, I googled for a long time and found some solutions.
The problem is that whenever I navigate to a url, this url will work while I'm inside the app itself, but once you bookmark it and return it will obviously return a 404 since that page doesn't exist.
Backbone.history.navigate('test', true);
This will navigate to http://www.domain.com/test, which is great, but once you refresh the same URL it returns a 404.
There are ways to get this to work with using a specific .htaccess file, but I'm building this inside an existing website, so I can't use this.
Is there a way in Backbone.js to revert to just using hashbangs? My url would then look like this `http://www.domain.com/#!/test
This might not be the cleanest URL, but at least it will work.
Or am I just missing something obvious here? It can't be that I'm the only person with this problem.
You're using pushState according to your url, so you've got 2 main options:
stop using pushState when starting Backbone history (which would be the equivalent of using a hashbang, except for SEO)
have your server return a page for every URL your app generates (it can be the same exact page)
In the second case, if you don't care about SEO, you can have a catch all rule always returning (e.g.) index.html containing your Backbone app. When you start Backbone's history, it will lokk at the URL and navigate to the proper page (although you might have a "double render" effect).
If you're worried about SEO, you need to return page content for SEO along with your Backbone app.
I have an Angularjs app running on Sinatra.
My Angular routes are working if I click on a link within the app, however if I visit the url directly I get a 404 from Sinatra.
Is there a way to pass the routing from Sinatra to Angular?
Currently all Sinatra is doing is loading the index.html
get '/' do
File.read "#{Dir.pwd}/app/index.html"
end
Thanks to #Ryan I ended up implementing a working solution.
get '/*' do
File.read "#{Dir.pwd}/app/index.html"
end
One way you could do this would be to set up a catch-all route with Sinatra to pass requests on to your angular app. I'm not very familiar with the sinatra framework, but for flask this is how you do it:
#app.route('/', defaults={'path': ''})
#app.route('/<path:path>')
def index(path):
return make_response(open('templates/index.html').read())
Just find the equivalent for Sinatra and you'll be good to go.
EDIT: I realized it is probably not the best idea to set up a catch-all route, especially if you are building a website (and using "$locationProvider.html5Mode(true)" vs. building a single-page webapp), for which returning proper 404's is important for search engine indexing, etc.
I would instead register a flask route for every route in your Angular app. In flask, this is how you do it.
#app.route('/')
#app.route('/about')
def index(path):
return make_response(open('templates/index.html').read())
In sinatra, I'd suppose it would be something like this:
get '/' do
get '/about' do
File.read "#{Dir.pwd}/app/index.html"
end
EDIT: It really depends what you're going for. Some sites want their entire site to be an angular app (and don't prioritize SEO, proper 404's, etc.) and others want a particular section to be reserved for their angular app. You might see "/app/OTHER_STUFF", for example. In that case, a catch all would work well.
Recently I found out about the undocumented $locationChangeStart event in AngularJS when trying to determine where in the framework I should be redirecting users to the login page if their session is invalid.
I'm listening for the event using the following:
$scope.$on("$locationChangeStart", function (event, nextLocation, currentLocation) {
// Logic goes here
});
where nextLocation and previousLocation are absolute urls to locations within the app.
My question is this: Does AngularJS expose the ability to be able to match a url against a route, much like its internal routing engine does to see if an absolute URL matches a defined route?
If not, what would be the best way to detect a route based on an absolute URL?
I located the relevant source code lines in the AngularJS github project. Here is the function that it uses to match the URL to a route:
Since this functionality is not exposed by Angular I decided to come up with a rudimentary way of matching the URL to a route since the routes I was matching were relatively simple compared to implementing the same route matching that Angular does.
It ain't pretty, but it works..