#/order/123?status=success
hits the route '/order/:id' and takes to OrderCtrl.
Once we access the $routeParams.query, we want to clear the url to #/order/123. How can this be achieved?
Using the $location service, you can remove the search param by assigning it a null value:
$location.search( 'status', null );
But you should note that, by default, this will reload the current route. If you don't want to reload the current route, you can disable that in your route definition:
$routeProvider.when( '/order/:id', {
// yada yada...
reloadOnSearch: false
});
But the $routeUpdate will still fire and can be reacted to.
A more efficient way to remove all search params would probably be
$location.search({});
Related
Using ASP.NET Identity, if I want to construct an <a> element that links to the Login page I can use Razor Helpers and some magic strings:
<a asp-area="Identity" asp-page="/Account/Login">Login</a>
(Not the question at hand, but I'd be happy if someone would tell me why this convoluted collection of magic strings is somehow better than hardcoding the "/Identity/Account/Login" relative URL.)
My question is: If I want to return a redirect from a Handler routine (i.e., the C# code behind a razor page), is there some recommended magic that I should be using to get a relative URL to the Login page?
In other words, is there something better than:
return Redirect("/Identity/Account/Login");
Use it this way:
return RedirectToPage("/Account/Login", new { area = "Identity" });
You may be missing RazorPages. Depending on how your mapping occurs in your program.cs, either add in your Web.config
services.AddRazorPages;
or in your .Net6 Programs.cs use
builder.Services.AddRazorPages;
or if you are using endpoints, replace
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "areas",
pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}"
);
});
with
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "areas",
pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
I'm using koa2 and koa-router together with sequelize on top. I want to be able to control user access based on their roles in the database, and it's been working somewhat so far. I made my own RBAC implementation, but I'm having some trouble.
I need to quit execution BEFORE any endpoint is hit if the user doesn't have access, considering endpoints can do any action (like inserting a new item etc.). This makes perfect sense, I realize I could potentially use transactions with Sequelize, but I find that would add more overhead and deadline is closing in.
My implementation so far looks somewhat like the following:
// initialize.js
initalizeRoutes()
initializeServerMiddleware()
Server middleware is registered after routes.
// function initializeRoutes
app.router = require('koa-router')
app.router.use('*', access_control(app))
require('./routes_init')
routes_init just runs a function which recursively parses a folder and imports all middleware definitions.
// function initializeServerMiddleware
// blah blah bunch of middleware
app.server.use(app.router.routes()).use(app.router.allowedMethods())
This is just regular koa-router.
However, the issue arises in access_control.
I have one file (access_control_definitions.js) where I specify named routes, their respective sequelize model name, and what rules exists for the route. (e.g. what role, if the owner is able to access their own resource...) I calculate whether the requester owns a resource by a route param (e.g. resource ID is ctx.params.id). However, in this implementation, params don't seem to be parsed. I don't think it's right that I have to manually parse the params before koa-router does it. Is anyone able to identify a better way based on this that would solve ctx.params not being filled with the actual named parameter?
edit: I also created a GitHub issue for this, considering it seems to me like there's some funny business going on.
So if you look at router.js
layerChain = matchedLayers.reduce(function(memo, layer) {
memo.push(function(ctx, next) {
ctx.captures = layer.captures(path, ctx.captures);
ctx.params = layer.params(path, ctx.captures, ctx.params);
ctx.routerName = layer.name;
return next();
});
return memo.concat(layer.stack);
}, []);
return compose(layerChain)(ctx, next);
What it does is that for every route function that you have, it add its own capturing layer to generate the params
Now this actually does make sense because you can have two middleware for same url with different parameters
router.use('/abc/:did', (ctx, next) => {
// ctx.router available
console.log('my request came here too', ctx.params.did)
if (next)
next();
});
router.get('/abc/:id', (ctx, next) => {
console.log('my request came here', ctx.params.id)
});
Now for the first handler a parameter id makes no sense and for the second one parameter did doesn't make any sense. Which means these parameters are specific to a handler and only make sense inside the handler. That is why it makes sense to not have the params that you expect to be there. I don't think it is a bug
And since you already found the workaround
const fromRouteId = pathToRegexp(ctx._matchedRoute).exec(ctx.captures[0])
You should use the same. Or a better one might be
var lastMatch = ctx.matched[ctx.matched.length-1];
params = lastMatch.params(ctx.originalUrl, lastMatch.captures(ctx.originalUrl), {})
I want to prevent a record from being deleted based on certain conditions in NetSuite. However, I can't seem to find a failure event on validation? BeforeSubmit on a UserEvent has a delete type, but it doesn't have a return value for the function, so I can't just say return false, can I?
How do I then prevent the deletion of a record, or fail a record submission of a certain type?
Instead of returning false, just throw an error. Not user friendly but it is the only option, as far as I know.
Since it is in the Before Submit User Event, the submission or deletion will fail.
You'll want to use a beforeSubmit user event script and throw an error using nlapiCreateError. Here's an example:
function beforeSubmit(type) {
if(type == 'delete') {
// NOTE `nlapiGetFieldValue` returns nil/empty during a delete event
// `nlapiGetOldRecord` needs to be used to pull the entire record
var payment = nlapiGetOldRecord();
if(payment.getFieldText('paymentmethod') == 'cash') {
throw nlapiCreateError(
'AN_ERROR',
'Message to the user!',
true
);
}
}
}
You can also use a Workflow to prevent the Delete button to display to the user:
You could add client-side code to pop up a message to the user when trying to delete a record you want to prevent. With that said, you would still want to put a UserEvent script preventing the delete actions as well. This would prevent the user from by passing the restriction
Follow up question: What is the code "res.json(false);" doing? Doesn't that print out false on the page instead of showing the data I want?
I'm looking at the following sample code. I understand that .get( is the method and /:characters? is the server path. In this search, what is the point of the colon and the question mark in the path? Shouldn't the question mark come before characters because it is a query?
app.get('/:characters?', function (req, res) {
var chosen = req.params.characters;
if (chosen) {
console.log(chosen);
for (var i = 0; i < characters.length; i++) {
if (chosen === characters[i].routeName) {
res.json(characters[i]);
return;
}
}
res.json(false);
} else {
res.json(characters);
}
});
In this case the question mark signifies an optional parameter "characters". This allows for an endpoint that MAY have a value or not. They are then testing against that parameter to see if it was included. If so they will iterate through the "characters" object and return any matching entry to the endpoint the user specified.
Simplest answer:
:XXX means that its a URL parameter. (i.e. req.params.XXX will pick up what the XXX is)
? means that the parameter is optional. (i.e. the client-side user doesn't need to include this parameter in the url).
So:
/:characters? would allow for: both / AND /yoda to hit this route.
:characters isn't actually part of the query string. It will be part of the url.
The url will be something similar to the following (assuming you are running this server locally and on port 8080):
http://localhost:8080/abcdefg
And in that case, req.params.characters will be 'abcdefg'
Putting an explicit question mark in the route definition is a mistake, in my opinion. I'm not entirely sure what purpose that question mark would serve.
For the follow up question, what it appears to be doing is looking for a match in the characters variable (which I assume is defined externally) by characters[i].routeName, and returning the found value. If no value is found, that's when it sends back false (or tries to - to be honest, I'm not sure what express will do if you try using res.json(false), since I'm not sure false is valid JSON).
This is a normal case that a endpoint or a resource can contain a variable that means
lets take facebook for example so if you see the timeline of MarkZukerberg then the endpoint or url is
https://www.facebook.com/zuck
if you see your own profile then that zuck will be replaced by your name. so the name parameter here is a variable.
When ever a variable is a part of the url then we precede that with a colon sign in express syntax
and if we want to send some other values as the query parameter then we use ? mark to tell the server that the following string will be a query parameter
?name=value&age=12&gender=male
And
res.json(false)
will just return false as the response nothing else
I am getting
Error: [$location:ihshprfx] Invalid url "http://localhost:3000/#", missing hash prefix "#!". http://errors.angularjs.org/1.2.16/$location/ihshprfx?p0=http%3A%2F%2Flocalhost%3A3000%2F%23&p1=%23
after delete function:
$scope.delete = function(venue) {
venue.$remove();
};
but venue is successfully removed. What could be wrong?
UPDATE: I saw that in a dropdown I wrote href = '#' . But when I delete it, nothing happens. How I can call directive from a tag?
Delete
Your ng-click calls a function called remove while your scope method is titled delete. Because it can't find the function you've set, I believe Angular doesn't to prevent the default event, which sends the user to '#', which is not valid based on your hash prefix settings.
If you match the function call to the method name, I think you should be fine.