HTML default URL param on page load - html

Task:
When I load page http://127.0.0.1:53132/pages/login.html I want it by default become http://127.0.0.1:53132/pages/login.html#/existinguser. Maybe someone can tell me how to make that?
I using html, angularjs.
Tried:<meta http-equiv="refresh" content="0; url=#/existinguser" /> but it keeps refreshing page infinitely.
ROUTE CONFIG
loginApp.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/existinguser', {
templateUrl: '../../pages/loginForms/existingUserForm.html',
controller: 'existingUserCtrlr'
})
.when('/newuser', {
templateUrl: '../../pages/loginForms/newUserForm.html',
controller: 'newUserCtrlr'
});
}]);

For default path use otherwise in routing config:
$routeProvider
.when('/existinguser', {
templateUrl: '../../pages/loginForms/existingUserForm.html',
controller: 'existingUserCtrlr'
})
.when('/newuser', {
templateUrl: '../../pages/loginForms/newUserForm.html',
controller: 'newUserCtrlr'
}).otherwise({
redirectTo: '/existinguser'
});
This means that if none of the defined routes exist in url when page loads, the path in the redirectTo will load

You need to define the default route in the router with the 'otherwise' option
When you first navigate to your site you probably load the index.html. that needs to redirect to the #/whatever route you want and the router then takes over from there.
Technically with the # you are still on the index.html page and you whole app is a single page, with the router routing requests on the client, not the server, but loading the proper template in the Dom to show the page you want, loading it from the server if needed (if not cached previously)
Try this doc
https://docs.angularjs.org/tutorial/step_07

Related

Redirect to external or internal link

I have a page in my application where backend decides where user should be redirected next. And it can be external link like 'google.com' or internal '/'. I use useNavigate hook from react-router-dom.
import { useNavigate } from "react-router-dom";
import axios from "axios";
useEffect(async () => {
await axios.get().then((response) => {
navigate(axios.redirectLink);
});
});
It perfectly works for internal links, but doesn't work for navigate('https://google.com'). Then it tries to open https://my-website/https://google.com. What might be a solution here?
There is no solution in navigating if you want a use Link tag do that else you can check this link as well
React-Router open Link in new tab
<Link to="your url" target="_blank">Test</Link>

Prefetch resources for async routes

Is there a way to prefetch or preload async routes? I'm exploring how to do this right now with RR2/3. The basic idea is I code split on every route but I'd like to be able to cache bundles for connected pages in a service worker before visiting that page. So what I'd like to do is have a custom <Link> that every time it's rendered, it tries to cache the resources of the page it's linked to. This would make page transitions considerably faster. What I don't know is if there's a way to emulate navigating to a route so that the resources will be fetched. Is there an API for this or some sort of tricky way to do this someone can think of?
This is what I came up. It's a component that wraps the React Router Link component and in componentDidMount (so only runs on the client not the server) check if in production (no need to run this during development) and if this is a browser that doesn't support Service Workers (this check is specific to my use case). Then manually match against the location and call any async getComponent functions.
import React from 'react'
import Link from 'react-router/lib/Link'
class GatsbyLink extends React.Component {
componentDidMount () {
// Only enable prefetching of Link resources in production and for browsers that
// don't support service workers *cough* Safari/IE *cough*.
if (process.env.NODE_ENV === 'production' && !('serviceWorker' in navigator)) {
const routes = require('my-routes')
const { createMemoryHistory } = require('history')
const matchRoutes = require('react-router/lib/matchRoutes')
const getComponents = require('react-router/lib/getComponents')
const createLocation = createMemoryHistory().createLocation
if (typeof routes !== 'undefined') {
matchRoutes([routes], createLocation(this.props.to), (error, nextState) => {
getComponents(nextState, () => console.log('loaded bundle(s) for ' + this.props.to))
})
}
}
}
render () {
return <Link {...this.props} />
}
}
module.exports = GatsbyLink
You could just do a require.ensure... section in a timeout when the Link is mounted. That should require the code split and load it up async. The timeout will ensure it get's loaded in a separate file.
I would recommend using RR4 for code splitting as I found in RR3 the async required routes get re-included and re-rendered if a child route changes. In my case, I had the componentWillMount of my routes being fired for any child route changes. e.g. Navigating from /agent/step-1 to /agent/step-2 will cause the Component for /agent to be unmounted and re-mounted.

Html5 mode Angularjs Express URL rewrite returns index page for ALL requests

I've been using similar questions to try and find the solution to the problem I'm having. I understand that in order to use html5Mode with angularjs I need to tell the server how to handle a direct visit to a page.
I have the issue where clicking on the link within the app renders the page fine but a direct visit does not display offers.
E.g.
http://localhost:3001/offers/television/
should call in routes.js
app.get('/offers', offers.all);
and it does when the link
televisions
is clicked
When I directly visit it however it looks like my angular service is returning the index page as resources...!
//Offers service used for offers REST endpoint
angular.module('mean.offers').factory("Offers", ['$resource','$routeParams',function($resource,$routeParams) {
return $resource('/offers/:offerId',
{offerId: '#_id'},
{
search: {'method': 'GET', params: {}, isArray:true}
});
}]);
I've also got base(href="/") in my index.jade head
angular config.js
//Setting up route
window.app.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/offers/:type/',{
controller: 'OffersController',
templateUrl: 'views/offers/list.html'
}).
when('/', {
templateUrl: 'views/index2.html'
}).
otherwise({
redirectTo: '/'
});
}
]);
//Setting HTML5 Location Mode
window.app.config(['$locationProvider',
function($locationProvider) {
$locationProvider.hashPrefix("!");
$locationProvider.html5Mode(true)
}
]);
express routes.js
//Offer Routes
var offers = require('../app/controllers/offers');
app.get('/offers', offers.all);
app.get('/offers/:offerId', offers.show);
//Home route
var index = require('../app/controllers/index');
app.get('/', index.render);
express.js
app.configure(function() {
// app.use('/', express.static(__dirname + '/'));
//cookieParser should be above session
app.use(express.cookieParser());
//bodyParser should be above methodOverride
app.use(express.bodyParser());
app.use(express.methodOverride());
//routes should be at the last
app.use(app.router);
app.get('/*', function(req, res) {
res.render('index');
});
...
Why is it not returning offers even though it should hit the /offers route in express routes.js? Or am I doing something odd?
Thanks!
As you mentioned in the comments of the question, "app.get('/offers', offers.all); will handle /offers/:offerId". This means that going directly to http://localhost:3001/offers/television/ will be handled by your offers.all function (not shown in post), not the '/*' handler that returns the index.
To fix this you have options.
Check the route to see if it is an AJAX request or not. If it is,
return your data, if it is not, return the index.
Put your API behind a path (like /api) then all of your API requests will go to
/api/offers/:offId to get data. This frees up /offers/:offerId
to be handled by '/*', returning the index
Edit:
I see the confusion, app.router (Node.js / Express.js - How does app.router work?). In a nutshell, app.use(app.router); tells express which order to run the routes as a whole. The order you provide the routes in matter after that point. From your code (again, not showing all of it) you only really define 1 route, app.get('/*', function(req, res) { res.render('index'); });. You have the separate route files, but no where in what you have posted do you includes those scripts. They are not automatically included by default.

AngularJS and Laravel 4 routing conflict in HTML5 mode

I would like to remove the # hash from URLs using Angularjs' $locationProvider.html5Mode(true).
Example: The address bar displays http://localhost/shop instead of http://localhost/#/shop.
Everything works well untill I refresh a page. If i refresh, the following Laravel Route (defined in routes.php) is accesed
Route::resource('shop', 'ShoppingController')
not the AngularJS Route (defined in app.js)
$routeProvider.when('/shop', {
templateUrl: 'templates/shop.html',
controller: 'ShoppingController'
});
My Code:
routes.php (Laravel Routes)
Route::get('/', function() {
return View::make('index');
});
Route::resource('shop', 'ShoppingController');
app.js (AngularJS Routes)
var app = angular.module('shoppingApp',['ngRoute','SharedServices']);
app.config(function($routeProvider, $locationProvider) {
$routeProvider.when('/shop', {
templateUrl: 'templates/shop.html',
controller: 'ShoppingController'
});
$routeProvider.otherwise({ redirectTo: '/' });
$locationProvider.html5Mode(true);
});
My directory structure:
Project
/app
/...
/views
-index.php (single page application file)
-routes.php (Laravel routes)
/public
/...
/js
-angular.js
-app.js
-index.php (Laravel index file)
Tried Solutions:
Rewrite the htaccess file so that all requests are redirected to index.php (the single page application file, from where AngularJS would take over the routing). Problem: In this way the Laravel route (Route::resource('shop', 'ShoppingController'); - necessary for interaction with the database) becomes inaccessible to the AngularJS $http service:
app.js
app.controller("ShoppingController", function($scope, $http) {
$http.get('/shop', { cache: true}).
success(function(data, status) {
$scope.items = data
}).
error(function(data, status) {
console.log('Status: ' + status);
});
});
Question:
How can I solve the routing problem, so that the AngularJS route, not the Laravel Route gets accessed if I refresh localhost/shop?
From what I read, it seems like Laravel is reading the modified route when you refresh the page. In this case, you should make Laravel continue to make the original view even if it would otherwise be a 404 redirect.
Try adding the following somewhere on the Laravel side (Ex. routes.php)
App::missing(function($exception)
{
return View::make('index');
});
Note: You might want to have AngularJS's routing use .otherwise to handle pages that are not found.
A better solution is to redirect this way:
'Redirect::to('/#/' . Request::path())'
When you refresh or go to the URI directly:
'Request::path()': returns the requested URI i.e.
('/shop/categories/electronics');
AngularJS in 'html5Mode' still responds to the '#/' prefix;
If angular detects the prefix when in HTML5 mode it will remove the prefix for you.
Final solution:
App::missing(function($exception) {
return Redirect::to('/#/' . Request::path());
});
If you are using Laravel 5 then go to app/Exception/Handler.php and place the code below:
public function render($request, Exception $e)
{
if($e instanceof NotFoundHttpException)
{
return Redirect::to('/#/' . Request::path());
}
return parent::render($request, $e);
}
If you wana have more than one single page application running in html5mode or just have another use for App::missing inside a Laravel app you migh use a rewrite rule like this:
#Redirect base url of AngularJS app in html5mode
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^/path/.+$
RewriteRule ^(path)/(.*) /path/#/$2 [R=301,L,NE]
I have another solution which I found quite useful. Rather than just making home page view, I pass in the URI to the home page, which will get checked by a controller and redirect accordingly (the Angular way). This means that if you are on myapp.com/about and you refresh, instead of taking you home, it takes you back to the page you were currently on.
routes.php: Notice that I have a URI wildcard that I pass in as an argument to the callback function, then as a variable to the view.
// Note that this must be on the bottom of your routes file because
// if you have any registered route with a similar pattern
// it will get caught by this route and never reach any registered routes you might have
Route::get('{slug}', function($slug){
return View::make('index', compact('slug'));
});
// These routes will never get hit, so move them above Route::get('{slug}')
Route::get('about', function(){...});
Route::get('contact', function(){...});
index.blade.php:
<html ng-app"myApp">
<head>
...
</head>
<body>
<!--Check if there is a variable named $slug that is set-->
<!--If it is, set hidden input with ng-model-->
#if(isset($slug))
<input type="hidden" value="{{slug}}" ng-model="slug" ng-controller="RedirectController">
#endif
<div ng-view></div>
</body>
</html>
app.js
angular.module('myApp', [])
.controller('RedirectController', ['$location', '$scope', function ($location, $scope) {
// If slug is set, redirect to that slug
if ($scope.slug) {
$location.path('/' + $scope.slug);
}
}]);
For Laravel 4.x or 5.x i use this simple and nice trick and there is no need to change .htaccess file. this trick is very simple and works for me. it doesn't redirect URL and user will stay on same URL when refresh page and page will refresh:
Route::get('dashboard/{all?}', function(){
return view('main.index');
});
here my dashboard app is my SPA. this way we can resolve 404 errors pages too.

angular routing something weird happening

I am still learning angularjs so maybe there's something stupid I am not understanding but I have a really strange behaviour when using routing.
In my application I use the following code to define my routes:
var app = angular.module('app', []);
app.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
$routeProvider.
when('/pneumatici/:chunka', {}).
when('/pneumatici/:chunka/:chunkb', {});
$locationProvider.html5Mode(true);
}]);
And in a controller I manage them this way:
app.controller('appCtrl', ['$scope', '$route', '$routeParams', '$location', function ($scope, $route, $routeParams, $location) {
$scope.$on('$routeChangeSuccess', function (current,previous) {
if (!($location.path().indexOf('/pneumatici') === -1)) {
$scope.chunka = $route.current.params.chunka; $scope.chunkb = $route.current.params.chunkb;
/** do my stuff with chunka and chunkb **/
} else {
window.location.href = $location.path();
}
});
I have no ngView, no template, nothing.
It works like a charm.
Please note the line where I actually force a page load in case the url is not intended to be managed by the controller appCtrl.
I was forced to do that because once I define my route to catch '$routeChangeSuccess' all links in the page when clicked are catched by angular and no page load occurs even if the link doesn't have the format defined with 'when'.
I would have like to do it with 'otherwise' but I could not understand how to, if doable.
Now the problem.
In the page of course I have links like just '/privacy.html', if I click them the page load is correctly triggered and I do see '/privacy.html' but unfortunately once there if I click the back button I can see the url of the browser changing to (let's say) /pneumatici/foo/bar but no page load is triggered.
Please note in the privacy.html page I have no angular routing defined, there's no .config no .when; there's an anagular app defined, with a controller, but no injection of '$routeProvider' anywhere, no definition of any route.
What is happening? What I am doing wrong?
Thanks for any help!
Update.
I found a viable solution adding:
angular.element("a").prop("target", "_self");
Angular routing is ignored for all 'a' elements with 'target' set to "_self", didn't know that.
Still if I look at this strategy as a whole doesn't sound very elegant to me and I would love to improve it. What I don't like is since I am defining the route in .config I should be able to tell angular to skip any url which do not match the format/path I defined there.
But I don't know if that is doable or not, does anyone know out there?
By turning on html5mode your app should be acting like it should intercept everything on the site by default (from '/'.)
From that perspective, it seems like $location.path() should work in your explicit override, but it isn't really correct ($location.url() would be) and the browser already has the correct URL, so maybe you can't force a reload with location.href = location.href in your specific browser.
Rather than going down that path, I would do the following to make it DRY:
If you add a base href:
<base href="/pneumatici/"></base>
and replace /pneumatici/ with / in your when clause(s):
$routeProvider.
when('/:chunka', {}).
when('/:chunka/:chunkb', {});
then you should just need this:
$scope.$on('$routeChangeSuccess', function (current,previous) {
$scope.chunka = $route.current.params.chunka;
$scope.chunkb = $route.current.params.chunkb;
/** do my stuff with chunka and chunkb **/
});
I think you should let Angular manage all your routes like this:
var app = angular.module('app', []).config(function($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true).hashPrefix('!');
$routeProvider
.when('/',
{
controller: 'HomeController',
templateUrl: '/partials/home.html'
})
.when('/about',
{
controller: 'AboutController',
templateUrl: '/partials/about.html'
})
.when('/privacy',
{
controller: 'PrivacyController',
templateUrl: '/partials/privacy.html'
})
.when('/404',
{
controller: 'NotFoundController',
templateUrl: '/partials/404.html',
})
.otherwise({
redirectTo: '/404'
});
});
Notice the otherwise above. That tells angular to load the 404 page when a route is not recognized.