Ui router Couldn't find views with Nodejs - node.js

I'm working on nodejs application we use the Ui router to implement single page application , I Created the controller in node js that load the Layout which have angular scripts and libraries , and then I tried to navigate throught the routes I defined in ui router , each time I got the error in the console said "angular.js:8081 GET http://localhost:2405/Views/Partials/Know-me.html 404 (Not Found)"
I can't specify the problem
this is some code :
Nodejs Controller
app.get("/",function(req , res){
res.render("Template.ejs"); // this is the layout
});
Layout Scripts :
<script src="http://code.angularjs.org/1.2.13/angular.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.8/angular-ui-router.min.js"></script>
<script src="../../angular_js/app_angular.js"></script>
and the app_angular script :
var appmodule = angular.module('mainApp',[ui.router]);
appmodule.config(function($stateProvider , $urlRouterProvider , $locationProvider){
$urlRouterProvider.otherwise('/things');
$stateProvider
.state('me',{
url : '/me',
templateUrl : '/Views/Partials/Know-me.html'
})
.state('amir',{
url : '/amir',
templateUrl : '/Know-me-amir.html'
});
//$locationProvider.html5Mode(true);
});
structure of the project :
-- View
--- Shared
---- Temaplte.ejs
--- Partials
---- know-me.html
-- Scripts
--- angular_js
---- angular_app.js

The problem is:
ejs files are rendered on the server. AngularJS (client) tries to fetch
'Views/Partials/Know-me.html'. From client's perspective this html does not exist.
Please do the following:
Add an public folder.
Serve the public folder with express.static()
Move the html files to this directory: public/Views/Partials/Know-me.html
Try to access http://localhost:2405/Views/Partials/Know-me.html - if you see the contents of know-me - your are good to go!
now your client will find the asyncronisly loaded html file.

Related

It doesn't seem to be getting my index.html file in my views directory. I get an error on the localhost 3000, cannot get

You can view my files in github at https://github.com/elmoreka/myTaskLIst.git.
It doesn't seem to be getting my index.html file in my views directory. I get an error on the localhost 3000, cannot get .
The index.html is not served because the path used for res.render() is incorrect.
In your file routes/index.js, the rendered path is:
res.render('views/index.html');
However, as the view root is defined as myTaskList/views, the above code would try to find file myTaskList/views/views/index.html, which does not exist. To fix this issue, the rendered path need to be as:
res.render('index.html');
As per Expressjs, index.html is a normal static file in your case, that needs to be sent from the server and rendered at the client(browser). Since you haven't used any template engine (ejs) for your index page then the correct expressjs API to be used is
res.sendFile('index.html');
and not
res.render('index.html'); // this is not ejs template file.
In server.js you are defining "client" as your static folder:
// Set Static folder
app.use(express.static(path.join(__dirname, 'client')));
If you want to serve a static file like your index.html you need to move it to your static folder "client". Then you can send it to the client with res.sendFile().

How to handle angular2 route path in Nodejs?

I am working on a NodeJS app with Angular2. In my app, I have a home page and search page. For home page I have an HTML page that will render for the localhost:3000/ and from home page user navigate to search i.e localhost:3000/search page that I handled by angular2 routes.
I don't have the page for the search page its view render by the angular2. But when I directly hit localhost:3000/search as I don't have this routing in my node app it gives the error.
I don't know How to handle this in node app?
If you enter localhost:3000/search directly in the browser navigation bar, your browser issues an request to '/search' to your server, which can be seen in the console (make sure you check the 'Preserve Log' button).
Navigated to http://localhost:3000/search
If you run a fully static server, this generates an error, as the search page does not exist on the server. Using express, for example, you can catch these requests and returns the index.html file. The angular2 bootstrap kicks-in, and the /search route described in your #RouteConfig is activated.
// example of express()
let app = express();
app.use(express.static(static_dir));
// Additional web services goes here
...
// 404 catch
app.all('*', (req: any, res: any) => {
console.log(`[TRACE] Server 404 request: ${req.originalUrl}`);
res.status(200).sendFile(index_file);
});
You need to use HashLocationStrategy
import { LocationStrategy, HashLocationStrategy } from "angular2/router";
bootstrap(AppComponent, [
ROUTER_PROVIDERS,
provide(LocationStrategy, { useClass: HashLocationStrategy })
]);
In your bootstrap file.
If you want to go with PathLocationStrategy ( without # ) you must setup rewrite strategy for your server.
I've been digging this topic for quite a time , and try a lot of method that don' work .
If you are using angular-cli and with express , I found a solution if the chosen answer doesn't works for you .
Try this node module : express-history-api-fallback
[ Angular ] Change your app.module.ts file , under #NgModule > imports as following :
RouterModule.forRoot(routes), ...
This is so called : " Location Strategy "
You probably were using " Hash Location Strategy " like this :
RouterModule.forRoot(routes, { useHash: true }) , ...
[ Express & Node ]
Basically you have to handle the URL properly , so if you want call "api/datas" etc. that doesn't conflict with the HTML5 Location Strategy .
In your server.js file ( if you used express generator , I've rename it as middleware.js for clarity )
Step 1. - Require the express-history-api-fallback module.
const fallback = require('express-history-api-fallback');
Step 2 . You may have a lot of routes module , sth. like :
app.use('/api/users, userRoutes);
app.use('/api/books, bookRoutes); ......
app.use('/', index); // Where you render your Angular 4 (dist/index.html)
Becareful with the order you are writing , in my case I call the module right under app.use('/',index);
app.use(fallback(__dirname + '/dist/index.html'));
* Make sure it is before where you handle 404 or sth. like that .
This approach works for me : )
I am using EAN stack (Angular4 with cli , Express , Node )

Deleted route function still serves old version of EJS file in Node/express App

I cannot reach modified version of my resource that is a html template, index.ejs, in uri '/' in my node-express app.
I have tried clearing and disabling Safari cache, restarting node server, even completely copy all the projects files to a new project dir, start server in another port etc.
Strange is that the version of the index.ejs file my browser shows in localhost:8080/ is non-existent. I have deleted it put the new one with new content. But I cannot view the new document in the browser in the '/' path, but only in another path, say '/i', if I set in server to respond with the same template, index.ejs.
Even if I delete the route function that serves index.ejs in path '/', it still serves it! How can this happen?
What can be the cause of this?
Old route to serve index.ejs that is deleted and still works when browser visited:
app.get('/', function(req, res) {
res.render('index.ejs');
});
New route to the modified version of the file index.ejs is not served with '/' path but only the old version of it is visible when '/' is visited. Following is the new route I have defined to be able to view the modified version of the index.ejs:
app.get('/i', function(req, res) {
res.render('index.ejs');
});
This issue occurred to me a few weeks ago when I was working on Node.js + Express + TS application. So apparently, I put some html files inside the public/ directory that I marked as static using express.static() because I was converting them to EJS so that I can later put those ejs files inside the views/ directory. Deleting those HTML files fixed my issue.

Angular and Sails routing configuration

Is there any Sails.js (or Node) configuration which can prevent Angular routing from working?
No matter what approach I take, every rout apart from ones in sails' routes.js return 404.
I've tried both 1.2 and 1.3 Angular versions, and I'm using Sails v 0.9.15.
All scripts are loaded in correct order (for example):
<script src="/linker/js/libs/angular/angular.js"></script>
<script src="/linker/js/libs/angular/angular-resource.js"></script>
<script src="/linker/js/libs/angular/angular-route.js"></script>
<script src="/linker/js/libs/angular/angular-sanitize.js"></script>
...
<script src="/linker/js/app.js"></script>
I'm using the ngRoute correctly:
var myApp= angular.module('myApp', ['ngRoute']);
Here are my routes in Angular's app.js:
myApp.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/profile',
{ templateUrl: 'linker/views/profile.html', controller: 'MainCtrl' })
.when('/profile-detail',
{ templateUrl: 'linker/views/profile_detail.html', controller: 'MainCtrl' });
}]);
And I'm also using location provider:
myApp.config(function ($locationProvider) {
$locationProvider.html5Mode(true);
});
Additional details:
ng-app and ng-view are correctly placed, and my paths are correct. I can correctly show profile.html with Angular (and also to include data from Sails' Restful API).
Problem is, that I can only do that for routes defined in Sails' routes.js.
Example:
module.exports.routes = {
'/' : {
controller: 'main',
action: 'index'
},
'/signup' : {
controller: 'main',
action: 'signup'
},
'/login' : {
controller: 'main',
action: 'login'
},
'/profile': {
controller: 'users',
action: 'profile'
} //......
So basically, in order to show some html content with Angular, I have to define EXACTLY THE SAME route in Sails' configuration, which makes no sense.
Any ideas? P.S. I'll provide additional data if needed.
Try removing the html5 mode to see what happens:
$locationProvider.html5Mode(false);
If you are using your sails application only to provide an API for your Angular app, but you are using the same backend to serve your angular code, then you could prefix all API routes with 'api' in order to prevent having conflicts with angular routes.
Instead of /profile you would have /api/profile
EDIT:
I've taken a look into the Sails.js framework and made a small app to test it.
I was able to successfully have routes in angular work that were not defined by sails.
I think there is a misunderstanding of how angular routing works.
If you change the path with window.location or type the url manually, the browser will send a get request to the server. So in your case, there will be a request for /profile or /profilee and the server will look at the available routes and will throw a 404 if nothing matches.
To prevent that, you should actually change the path using angular methods. Angular uses the '#' symbol in the path to prevent the browser of sending requests to the server when the url changes. Browsers ignore changes after the '#' symbol. Or in your case, a similar effect is achieved using the html5 mode. Beware though that using html5 mode can cause troubles when users refresh the page, since then a request will be made to the server (more on how to fix that below).
So, what you should be using to change the paths with javascript is the $location service. In your angular views, you can also use normal anchor tags like, because angular parses those:
Go to profile
Since what you have is a single page application, alls views are handled by the client. All the paths beyond the root (/) are virtual paths created by angular. They usually don't exist in the server. Only the root is available. When using html5 mode that can be a problem.
A way to fix that is to rewrite the routing of the server to serve everything else as if it was a request to the root path. In sails they even suggest how to do that in the config/routes.js:
// What about the ever-popular "vanity URLs" aka URL slugs?
// (you might remember doing this with `mod_rewrite` in Apache)
//
// This is where you want to set up root-relative dynamic routes like:
// http://yourwebsite.com/twinkletoez
//
// NOTE:
// You'll still want to allow requests through to the static assets,
// so we need to set up this route to ignore URLs that have a trailing ".":
// (e.g. your javascript, CSS, and image files)
'get /*(^.*)': 'UserController.profile'
Regarding the API in sail, you can configure a prefix inside the config/controllers.js file:
/**
* `prefix`
*
* An optional mount path for all blueprint routes on a controller, including `rest`,
* `actions`, and `shortcuts`. This allows you to continue to use blueprints, even if you
* need to namespace your API methods.
*
* For example, `prefix: '/api/v2'` would make the following REST blueprint routes
* for a FooController:
*
* `GET /api/v2/foo/:id?`
* `POST /api/v2/foo`
* `PUT /api/v2/foo/:id`
* `DELETE /api/v2/foo/:id`
*
* By default, no prefix is used.
*/
prefix: '',

Uploadify Script is not working when inside kohana controller

Hello I am trying to implement the uploadify script in kohana 2.3.4, it works when i place the uploadify script on the root directory then point it out on my view file. But when I point the script to a controllr, it returns a http error. Below is the js script:
<script type="text/javascript">
// <![CDATA[
$(document).ready(function() {
$('#file_upload').uploadify({
'uploader' : '<?=url::base()?>uploadify/uploadify.swf',
'script' : '<?=url::base()?>uploadify', /*Even tried http://localhost/directory/uploadify*/
'cancelImg' : '<?=url::base()?>uploadify/cancel.png',
'folder' : '<?=url::base().$directory?>',
'multi' : true,
'removeCompleted' : false,
'auto' : true
});
});
// ]]>
</script>
Not sure what error you were receiving but if your page requires authentication and controller not able to authenticate user then you can follow my solution.
Problem is that uploadify uses flash and there is bug in flash that it does not sent cookies to server.
I changed it at shown below to get it working.
in js (for kohana)
$('#file_upload').uploadify({
uploader: base_url+"upload/image?sess=<?php Session::instance()->id(); ?>",
});
and in plain php
$('#file_upload').uploadify({
uploader: base_url+"upload/image?sess=<?php session_id();?>",
});
and in kohana controller while reading authentication from session, initialize session as following
$sess_id = Arr::get($_GET,'sess',null);
$sess = Session::instance(null,$sess_id);
or in plain php
session_name($_GET['sess']);
session_start();
in future if bug in flash is fixed then there will be no need to do this

Resources