If I am in http://localhost:3000/Authpage I want to redirect to new URL http://www.example.com/
Usehostory() -> histor.push() is appending new url to old url.
http://localhost:3000/Authpage/http://www.example.com/
But I need new location something like below
http://www.example.com/
You can have a look at this thread here for an answer.
To summarize it, in your event handler you can add
const eventHandler = () => {
window.location.assign('http://www.example.com/')
}
However, the way I see it, it's just easier to create a simple regular HTML <a> tag:
<a href='http://www.example.com/'>click to redirect</a>
you have 2 options
use tag to redirect the user into a new web page.
or use one of the javascript methods like window.open("yourUrl.com")
but be careful when you are using javascript methods to redirect the user because the safari browser would not let you use some of them( because of some security filters)
You should use window.location.assign. For example
handleClick() {
window.location.assign('http://www.example.com/');
}
render() {
return (
<button onClick={this.handleClick.bind(this)} />
);
}`
Related
I have two different react applications, one for customer and one for admin.
Customer app runs on port 3000 and admin on 3001.
I have a button where I want to change from the admin page to the customer page and vice versa.
For now, I am using window.location.href to reload to another url and this works, like this :
onClick={event => window.location.href='http://localhost:3000/customerloginpage'}
I tried redirect and routes and using history but what happens is that it adds the url to the end of the current url instead of replacing ,example :
const history = useHistory();
const customerButtonClicked = () =>{
let path = 'http://localhost:3000/customerloginpage';
history.push(path);
}
Example result :
'http://localhost:3001/adminloginpage/http://localhost:3000/customerloginpage'
Is there a way to do this without having to reload the page with window.location.href? Please explain this concept to me, thanks!
I'm serving my website from example.org, built with reactjs 16.13.1 and typescript.
I have a component that displays an image like this:
<img alt={""} className={"person-image"} src={person.imageUrl}/>
The person JSON object comes from the backend. ImageUrl is an url that looks like this: https://example.org/api/data/24361/img.jpg. The image is served via a Spring Boot controller.
The image fails to load because for some reason it is rewritten to: https://example.org/example.org/api/data/24361/img.jpg
Why is example.org being repeated?
I inspected the JSON returned from the server and the url is correct: https://example.org/api/data/24361/img.jpg
If I copy paste the url on a browser, it loads correctly, so it's not a reverse proxy problem, or it doesn't seem to be.
If I log the url on the console before it's being passed to <img>, it is correct.
I have some other images being loaded from external domains and they load without any issue.
Is the <img> tag operating some kind of rewriting of the url if the image comes from the same domain and an absolute url is being used? Is there something I'm overseeing?
EDIT: the component code
interface PersonProps {
person: PersonData
clickable?: boolean
}
export function Person({person}: PersonProps) {
const actions = [
new Action(
<><FullscreenOutlined/> Full</>,
() => {
// opens wrong url https://example.org/example.org/api/data/24361/img.jpg
const win = window.open(person.imageUrl, '_blank');
win?.focus();
}
)
]
// prints https://example.org/api/data/24361/img.jpg
console.log(person.imageUrl)
return <Wrapper
actions={actions}>
{/* loads wrong url https://example.org/example.org/api/data/24361/img.jpg */}
<img alt={""} className={"person-image"} src={person.imageUrl}/>
<div className={"person-body"}>
{person.name}
</div>
</Wrapper>
}
I have setup gatsby project using this link. It is working correctly.
Now I know how to create route by defining the component inside the pages folder. But now I have a new challenge I need to create one dynamic route so that I can pass my id in it (Just like reactjs).
<Route path: "/path/:id"/>
How do I do that in gatsby?
You have to explicitly tell gatsby that a path should be dynamic. From the docs:
// gatsby-node.js
// Implement the Gatsby API “onCreatePage”. This is
// called after every page is created.
exports.onCreatePage = async ({ page, actions }) => {
const { createPage } = actions
// page.matchPath is a special key that's used for matching pages
// only on the client.
if (page.path.match(/^\/app/)) {
page.matchPath = "/app/*"
// Update the page.
createPage(page)
}
}
and then you can use dynamic routing in src/pages/app.js
import { Router } from "#reach/router"
const SomeSubPage = props => {
return <div>Hi from SubPage with id: {props.id}</div>
}
const App = () => (
<Layout>
<Link to="/app/1">First item</Link>{" "}
<Link to="/app/2">Second item</Link>{" "}
<Router>
// ...dynamic routes here
<SomeSubPage path="/app/:id" />
</Router>
</Layout>
)
export default App
Everything that goes to /app/* will be handled dynamically now. You should find your id as usual in the props.
Have a look at their authentication example https://github.com/gatsbyjs/gatsby/tree/master/examples/simple-auth
You can use square brackets ([ ]) in the file path to mark any dynamic segments of the URL. For example, in order to edit a user, you might want a route like /user/:id to fetch the data for whatever id is passed into the URL.
src/pages/users/[id].js will generate a route like /users/:id
src/pages/users/[id]/group/[groupId].js will generate a route like /users/:id/group/:groupId
Reference: https://www.gatsbyjs.com/docs/reference/routing/file-system-route-api#creating-client-only-routes
You can use gatsby-plugin-create-client-paths. It uses matchPath. For more info check
https://www.gatsbyjs.org/docs/gatsby-internals-terminology/#matchpath
https://www.gatsbyjs.org/packages/gatsby-plugin-create-client-paths/
This answer is Super late, but for anyone in the future who is faced with this problem, I have a simpler solution.
In Gatsby terms it's called a Splat Route.
For examples, If you want some page "domain.com/profile/[id]", where id can be any number, which will be used to display different data inside the website, you should name your page as [...id].
Now inside the page you can access this id as
const ProfilePage = (props) => <div>This page is for id number {props.params.id}</div>
Note: Don't miss the 3 dots, that is what signifies a splat route in gatsby.
I am learning React and want to create an application with Symfony4 as my backend and React frontend. I am stuck now when I need to pass some kind of data to the frontend from my backend. I don't really know what is the right way to do it? Following some tutorials I am doing it like this:
From the controller I send some data to the twig file:
/**
* #Route("/")
*/
public function homepage()
{
$date = new DateTime();
$curr_date = $date->format('Y-m-d H:i:s');
return $this->render('base.html.twig', [
'gameDate' => $curr_date
]);
}
In the twig file, I set it as a data-attribute
base.html.twig:
<div id="root" data-event-date="{{ gameDate }}">
Then I can get the variable as a dataset in my JavaScript
App.js:
const root = document.getElementById('root');
ReactDOM.render(<Homepage {...(root.dataset)}/>, root);
And render it from props.
Homepage.js:
class Homepage extends Component {
constructor(props) {
super(props)
this.state = {
prizePool: '',
gameDate: '',
numberOfPlayers: ''
}
}
onParticipateClick = (event) => {
this.setState({prizePool: Math.random()})
}
render()
{
return (
<div className="mt-c-10">
<GameInfoBox gameDate={this.props.eventDate}/>
</div>
)
}
}
This actually works, but I am concerned with showing all the information in data variables because anyone can see it. What if I want to pass user ID or something secret? There should be another way to do it right?
It depend on what you attemps, if you are working on big project, you can use API to serve backend data. Take a look here: https://www.modernjsforphpdevs.com/react-symfony-4-starter-repo/. There is a simple example.
But if you want something more use api-platform or FOSRestBundle.
"Best and safest" is a little ambiguous - do you need strict security, or safe as in code stability etc?
Instead of passing your data from controller to view (twig) and then into HTML elements or global, another way is this:
Controller loads the view file with your nav and other stuff
Controller loads React (however you do this, Webpack etc)
React calls another controller (i.e. fetch()). This controller is probably somewhere like src/Api/Controller/ as it wont render a view so keep it separate to the other controllers which do render a view
The API controller calls your DB or remote API (etc) and gets the data and sends it back as JsonResponse back to React.
React can then show the data, or an error message depending on the response status
The API controller in your MW can also handle errors and do some logging, so React just gets a 200 and the data or a 400 (or whatever) and it can show a nice message to the user as normal.
I am building an angular application and want to implement password reset. However, default laravel config doesn't appear to allow one to do this using purely XMLHttpRequest ($http.post) requests and responds with a 302 redirect.
I managed to get postLogin and postRegister to work without issuing redirects by implementing said methods in authController class and returning a json response, doing this overrides the default laravel implementation of said methods. No such luck with postEmail and it appears the method is not hit at all, I just get a 302 response back immediately.
Ideally, other than to check their E-mail, I don't want the user to leave the single page angular application at all.
So 1. User posts E-mail to postEmail -> Email with reset link or better 'reset code' is sent to E-mail address -> User then inputs the reset token code into the already open web app or if it can't be done, browse to reset password page opened in new tab.
I tried implementing postEmail method as such:
public function postEmail(Request $request)
{
$this->validate($request, ['email' => 'required|email']);
$response = Password::sendResetLink($request->only('email'), function (Message $message) {
$message->subject($this->getEmailSubject());
});
switch ($response) {
case Password::RESET_LINK_SENT:
return response()->json(['msg' => 'A reset link has been sent to your E-mail'], 200);
case Password::INVALID_USER:
return response()->json(['msg' => 'This E-mail cannot be found in our system'], 200);
}
}
Also, where is template for the E-mail with the reset link that laravel sends out ?
You can create a PasswordController within the App\Http\Controllers\Auth namespace to extend the password reset methods.
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Contracts\Auth\PasswordBroker;
use Illuminate\Foundation\Auth\ResetsPasswords;
class PasswordController extends Controller
{
use ResetsPasswords;
public function postEmail(Request $request)
{
}
}
To overwrite the email templates you can create a reminder.blade.php in the app/views/emails/auth directory, or change the location of the template file in the app/config/auth.php config.
while the accepted answer is completely valid, another solution without overriding the original notification class is as follows, ResetPassword provides a static method called createUrlUsing which accepts a Closure, So we can override the URL as something like the below:
use Illuminate\Support\Facades\Password;
use Illuminate\Auth\Notifications\ResetPassword;
...
$status = Password::sendResetLink(
['email' => $args['email']],
function ($user, $token) {
ResetPassword::createUrlUsing(function ($notifiable, $token) {
// This is where you override the URL, you can also take a look at
// the `url`, `action` and `route` functions in Laravel and skip
// `sprintf` if you prefer to stick to Laravel functions only.
return sprintf(
"%s/%s/?token=%s&email=%s",
config('your.optional.frontend_url'),
config('your.optional.password_reset'),
$token,
$notifiable->getEmailForPasswordReset(),
); // frontend_url/password_url/?token=TOKEN&email=EMAIL
});
return $user->notify(new ResetPassword($token));
}
);
// This is an optional way to handle the final response, you can convert it to
// JSON or ignore it.
return $status === Password::RESET_LINK_SENT
? ['status' => __($status)]
: throw new Error(__($status));
This piece of code should be placed at a new route to handle password reset requests instead of using the default Laravel one.