I have two separate folders for my project, one has Laravel for backend part named as 'backend' and another has angularjs for frontend part named as frontend. My question is how to routing from laravel to angularjs?
I tried to do
Route::get('/', function () {
return view('index.html'); // 'index.html' is located at /project/frontend
});
Route::group(array('prefix' => 'api'), function() {
Route::resource('todos', 'TodoController');
});
in
/project/backend/routes/web.php
and I also changed paths in
/project/backend/config/view.php
to
'paths' => array(__DIR__.'/../frontend'),
This gives me
InvalidArgumentException View [index.html] not found
I think it is because I was not able to locate the right index.html file. I am new to Laravel and AngularJS, please help me!
Related
I was trying to use Koa.js instead of express for node.js.
In express we have used render function to fetch the html page.
I tried to access angular html page from Koa.js using the below code as below:
app.use(async function (ctx, next) {
return send(ctx, 'views/index.html', { root: ''
})
.then(() => next()) })
But the above code displays the index page as it is without styles and the ng-view datas are not rendered
Also, I tried adding co-views as below
var views = require('co-views');
var render= views(__dirname + '/views',
{ map: { html: 'swig' }});
But, I didnt get the result as expected. It also displays the page as mentioned above.
Please help to get the expected result.
Unless you have very specific requirements for serving static files, most of the time you can get away with koa-static:
import serve from 'koa-static'
// ...
app.use(serve(`${__dirname}/public`))
If you have more particular needs, you might need to edit your question.
I have a sample MVC6 single page app with one view in which I want to load 2 Angular partials using ngRoute. You can have a look at it at GitHub
There are 3 URLs in the app:
localhost - Index.cshtml
localhost/games - Index.cshtml with Angular's gamelist.html partial
localhost/games/2 - Index.cshtml with Angular's game.html partial
The routes config is the following:
MVC:
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}");
routes.MapRoute("gamelist", "games", new { controller = "Home", action = "Index"});
routes.MapRoute("gameWithId", "games/2", new { controller = "Home", action = "Index" });
});
Angular:
myApp.config(['$routeProvider', '$locationProvider',
function ($routeProvider, $locationProvider) {
$routeProvider
.when('/games', {
templateUrl: 'partials/gameslist.html',
controller: 'GameController',
controllerAs: 'ctrl'
})
.when('/games/:gameId', {
templateUrl: 'partials/game.html',
controller: 'GameController',
controllerAs: 'ctrl'
});
$locationProvider.html5Mode(true);
}]);
It all works perfectly fine as long as I start the app from the home page '/' and then navigate to the partials using the links on the page. The problem is that the URL #3 (localhost/games/2) does not work if I start the app from it, by typing it in the address bar. The URL #2 (/games/) does work.
The reason why #3 does not work is that MVC removes '/games' part from the URL and what Angular gets is just '/2'. If you run the sample app, you will see that '$location.path = /2'. Of course Angular cannot map using that path and no partial is rendered. So my question is - how to make MVC return the full path to the client so that Angular can map it?
You can get it to work with HTML5 mode, you just need to ensure that every request maps back to your Index.cshtml view. At that point the AngularJS framework loads, client-side routing kicks in and evaluates the request URI and loads the appropriate controller and view.
We've done this with multiple Angular apps inside MVC with different .cshtml pages, though we use attribute routing with the wildcard character, e.g.
[Route("{*anything}")]
public ActionResult Index()
{
return View("Index");
}
The wildcard operator (*) tells the routing engine that the rest of the URI should be matched to the anything parameter.
I haven't had chance to get to grips with MVC6 yet but I think you can do something like this with the "new" version of attribute routing?
[HttpGet("{*anything:regex(^(.*)?$)}"]
public ActionResult Index()
{
return View("Index");
}
To make link #3 work from the browser's address bar, I turned off "html5Mode" in Angular and made links #-based.
kudos to this blog
I think it is a better solution.
His solution is rewriting the request that doesn't fit to any route and doesn't have any extension to the landing page of angular.
Here is the code.
public class Startup
{
public void Configure(IApplicationBuilder app, IApplicationEnvironment environment)
{
// Route all unknown requests to app root
app.Use(async (context, next) =>
{
await next();
// If there's no available file and the request doesn't contain an extension, we're probably trying to access a page.
// Rewrite request to use app root
if (context.Response.StatusCode == 404 && !Path.HasExtension(context.Request.Path.Value))
{
context.Request.Path = "/app/index.html"; // Put your Angular root page here
await next();
}
});
// Serve wwwroot as root
app.UseFileServer();
// Serve /node_modules as a separate root (for packages that use other npm modules client side)
app.UseFileServer(new FileServerOptions()
{
// Set root of file server
FileProvider = new PhysicalFileProvider(Path.Combine(environment.ApplicationBasePath, "node_modules")),
// Only react to requests that match this path
RequestPath = "/node_modules",
// Don't expose file system
EnableDirectoryBrowsing = false
});
}
}
I am creating a NodeJS app which uses AngularJS for it's front-end. I am Also using RequireJS to load in the JS dependencies and then instantiate the Angular app. Here is what I am trying to do:
Within my HTML file (written in Jade) I include the RequireJS files and then call the RequireJS config using the 'data-main' attribute:
doctype html
html
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
body
block content
script(type="text/javascript" src="/bower_components/requirejs/require.js" data-main="/main.js")
My main.js file looks as follows:
"use strict";
function(require) {
require(['/assets/requiredPathsAndShim.js'], function(requiredPathsAndShim) {
require.config({
maps : {
// Maps
},
paths : requiredPathsAndShim.paths,
shim : {
// Modules and their dependent modules
}
});
angular.bootstrap(document, ['appNameInHere']);
});
})(require);
I have an external file which contains an object with my routes '/assets/requiredPathsAndShim.js' and it looks like follows:
"use strict";
(function(define) {
define([], function() {
return {
paths : {
'angular' : '/bower_components/angular/angular'
}
};
});
})(define);
I will add that my NodeJS/Express app has the 'bower_components' folder set to serve static files and this is working fine.
Whenever I try and instantiate the AngularJS app using the 'angular.bootstrap...' method it tells me Angular is not defined. I can't see why this is happening and haven't been able to figure it out yet. O can't see any problem with my routes to the Angular files. Can anyone see or suggest why this may be happening?
Thanks!
Just managed to crack it! I had to place the 'angular.bootstrap' call in a callback function of the require.config method as the app was trying to call AngularJS before it had been defined.
Hope this helps anyone in the future.
I'm extending an existing Angular-MVC.NET application.
There are two features: transformations (exisitng) and embossing (the one I'm creating). Both of them use provider classes that call an underlying logic.
I copied all the logic for the transformation (Angular and MVC model and views), renamed evrthing accordingly, and created the new route for this feature in app.router.js
$routeProvider.when('/embossing', {
templateUrl: 'app/views/embossing.html',
params: { test: "hola" },
resolve: {
deps: [
"$ocLazyLoad", function (a) {
debugger;
return a.load([jqload.c3, jqload.sparkline])
.then(function () {
return a.load({
name: "app.directives",
files: ["app/scripts/lazyload/directives/sparkline.directive.js"]
});
})
.then(function () {
return a.load("angular-c3");
})
.then(function () {
return a.load("easypiechart");
});
}
]
}
});
Now I'm able to navigate without issues from the angular transformation controller to the embossing view by using
$location.path('/embossing');
The thing that happens is that when I load directly the view by entering http://localhost:1623/embossing/ or if I hit enter on the browrser's URL bar after navegating from transformation (as I mentioned before) I get this error
How come I'm able to navigate to the view but when I load it directly I get that error?
Is there something that I'm missing? What could be wrong?
Thanks
MVC and AngularJS Routing - 403.14 - Forbidden
It got solved by renaming the "Embossing" folder (the one that contains EmbossingProvider.cs)
It seems that there cannot be a folder name as a route. eg:
$routeProvider.when('/embossing', was conflicting with "Embossing" folder
So I've been trying to find a solution for my problem during the last 7 days or so. I have almost given up on this so this is my last attempt at solving this.
I'm trying to build a recipe site which fetches the recipes from my Laravel API Backend (i.e. api/recipes returns all recipes in the MySQL-database). The data is requested from the AngularJS frontend via the $http-service, so far so good.
Single page applications like this isn't a problem since I've defined the routes in Laravel like this. All HTTP reqs who isn't sent to the RESTful API is redirect to my index-view where I want AngularJS to take over the routing from there on.
Route::get('/', function()
{
return View::make('index');
});
Route::group(array('prefix' => 'api'), function() {
Route::resource('recipes', 'RecipeController',
array('except' => array('create', 'edit', 'update')));
Route::resource('ingredients', 'IngredientController',
array('except' => array('create', 'edit', 'update')));
Route::resource('nutrients', 'NutrientController',
array('except' => array('create', 'edit', 'update')));
Route::resource('IngredientsByRecipe', 'IngredientsByRecipeController');
});
App::missing(function($exception)
{
return View::make('index');
});
I want the user to be able to edit existing recipes, create new ones etc. Therefore I've created these routes in Angular:
var recipeApp = angular.module('recipeApp', [
'ngRoute',
]);
recipeApp.config(['$routeProvider',
function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'list.html',
controller: 'MainCtrl'
})
.when('/edit/:recipeId', {
templateUrl: 'detail.html',
controller: 'EditCtrl'
})
.when('/new', {
templateUrl: 'detail.html',
controller: 'CreateCtrl'
})
.otherwise({
redirectTo: '/'
});
}
]);
Unfortunately I can't seem to get this to work even with this routing in Angular. I've seen similar problems being solved by decoupling the app and stuff like that, and I've tried something like that by running my Angular frontend at port 8888 and the Laravel backend at port 8000 but then I got a problem with CORS.
I'm eager to get this to work but can't seem to figure out how to get it to work. It seems like the browser ignores the Angular routing and only uses the Laravel routing, which means that I can only access the index view or the API. How should I solve this?
Building hybrid apps like this is something I would not recommend. You should separate your Laravel API backend from your AngularJS frontend. You can then set up services in AngularJS to call your API. API driven development is the way to go.
If you have problems with CORS, you can modify the headers in your Laravel responses to fix this. To fix the problem with every Laravel route, you can add the following somewhere at the top of your routes.php file:
header('Access-Control-Allow-Origin: *');
Or (better solution if you want it for all routes), add this to your after filter in filters.php:
$response->headers->set('Access-Control-Allow-Origin', '*');
Or you can set up a separate filter:
Route::filter('allowOrigin', function($route, $request, $response) {
$response->header('Access-Control-Allow-Origin', '*');
});
Now, to answer your question ...
In the head of your index file (for Angular), add <base href="/">, and also add $locationProvider.html5Mode(true); inside your Angular config; you can just place it after your $routeProvider.when('/', { ... }); function.