react-router > redirect does not work - redirect

I have searched on the internet for this topic and I have found many different answer but they just do not work.
I want to make a real redirect with react-router to the '/' path from code. The browserHistory.push('/') code only changes the url in the web browser but the view is not refreshed by browser. I need to hit a refresh manually to see the requested content.
'window.location = 'http://web.example.com:8080/myapp/'' works perfectly but i do not want to hardcode the full uri in my javascript code.
Could you please provide me a working solution?
I use react ^15.1.0 and react-router ^2.4.1.
My full example:
export default class Logout extends React.Component {
handleLogoutClick() {
console.info('Logging off...');
auth.logout(this.doRedirect());
};
doRedirect() {
console.info('redirecting...');
//window.location = 'http://web.example.com:8080/myapp/';
browserHistory.push('/')
}
render() {
return (
<div style={style.text}>
<h3>Are you sure that you want to log off?</h3>
<Button bsStyle="primary" onClick={this.handleLogoutClick.bind(this)}>Yes</Button>
</div>
);
}
}

You can use router.push() instead of using the history. To do so, you can use the context or the withRouter HoC, which is better than using the context directly:
import { withRouter } from 'react-router';
class Logout extends React.Component {
handleLogoutClick() {
console.info('Logging off...');
auth.logout(this.doRedirect());
};
doRedirect() {
this.props.router.push('/') // use the router's push to redirect
}
render() {
return (
<div style={style.text}>
<h3>Are you sure that you want to log off?</h3>
<Button bsStyle="primary" onClick={this.handleLogoutClick.bind(this)}>Yes</Button>
</div>
);
}
}
export default withRouter(Logout); // wrap with the withRouter HoC to inject router to the props, instead of using context

Solution:
AppHistory.js
import { createHashHistory } from 'history';
import { useRouterHistory } from 'react-router';
const appHistory = useRouterHistory(createHashHistory)({
queryKey: false
});
export default appHistory;
Then you can use appHistory from everywhere in your app.
App.js
import appHistory from './AppHistory';
...
ReactDom.render(
<Router history={appHistory} onUpdate={() => window.scrollTo(0, 0)}>
...
</Router>,
document.getElementById('root')
);
Logout.js
import React from 'react';
import appHistory from '../../AppHistory';
import auth from '../auth/Auth';
import Button from "react-bootstrap/lib/Button";
export default class Logout extends React.Component {
handleLogoutClick() {
auth.logout(this.doRedirect());
}
doRedirect() {
appHistory.push('/');
}
render() {
return (
<div style={style.text}>
<h3>Are you sure that you want to log off?</h3>
<Button bsStyle="primary" onClick={this.handleLogoutClick.bind(this)}>Yes</Button>
</div>
);
}
}
this topic helped me a lot:
Programmatically navigate using react router

Related

React App deployed in LWC component of salesforce

I have deployed React App in LWC component without using Aura container basically bundle react application with webpack as static resource and use them inside a LWC and able to render.
able to open individual stylesheet for debugging purpose.
Question: Not able to debug the code/not opening individual JS file/component in developer console.
lwcReactContainer.html
<template>
<div id="react-app-root"></div>
</template>
lwcReactContainer.js
import { LightningElement, wire } from 'lwc';
import { loadScript, loadStyle } from 'lightning/platformResourceLoader';
import SPMLayoutEditor1 from '#salesforce/resourceUrl/SPMLayoutEditor1';
//import myStaticStyles from '#salesforce/resourceUrl/myStaticStyles';
import {
APPLICATION_SCOPE,
createMessageContext,
MessageContext,
publish,
releaseMessageContext,
subscribe,
unsubscribe,
} from 'lightning/messageService';
import getContactList from '#salesforce/apex/ContactController.getContactList';
export default class LWCReactContainer extends LightningElement {
renderedCallback() {
this.apiInProgress = true;
Promise.all([
loadScript(this, SPMLayoutEditor1 + '/FSLMAX_LayoutEditor/static/js/main.js'),
loadStyle(this, SPMLayoutEditor1 + '/FSLMAX_LayoutEditor/static/css/main.css'),
this.getUserInfo(), this.getContactList(), this.fetchObjectList()
]).then((data) => {
const contacts = data[3];
mount(this.template.querySelector('div'), { contacts });
});
}

Experiencing redirect loop with a protected route in Gatsby using Auth0 [duplicate]

This question already has an answer here:
Login doesn't show up in Gatsby using Auth0, withAuthenticationRequired
(1 answer)
Closed 1 year ago.
Note: This question is not a duplicate, I'm not sure why anyone is thinking that...
I’m having issue with implementing protected pages(routes) in Gatsby with Auth0
Currently, when I point the browser to localhost:8000/user/protectedpage, it goes to the login screen, and after a successful login, it comes back to that route, and the browser seems to be stuck on a loop loading between two routes.
When I tested with this, the page was doing a indefinite redirect loop while showing "Redirect..." on the page:
export default withAuthenticationRequired(ProtectedPage, {
onRedirecting: () => <div>Redirecting...</div>
});
redirectUri in Auth0Provider is set to redirectUri={window.location.origin + '/user'}
Allowed Callback URLs in the auth0 admin page, is set to, http://localhost:8000/user
If I change these routes to window.location.origin and http://localhost:8000/, then after a successful login, it’ll redirect to that page and stay there.
I need it to redirect to where it was trying to go to instead.
As in, if I navigate to localhost:8000/user/protectedpage, then after logging in, it should redirect to that route and load that page successfully, instead of being stuck in a loop like mentioned earlier.
Here are some codes:
// File structure
src
> pages
> user
> index.js
> protectedpage
index.js
gatsby-browser.js
// gatsby-browser.js
import React from 'react';
import { Auth0Provider } from '#auth0/auth0-react';
import { navigate } from 'gatsby';
const onRedirectCallback = (appState) => {
navigate(appState?.returnTo || '/', { replace: true });
};
export const wrapRootElement = ({ element }) => {
return (
<Auth0Provider
domain={process.env.AUTH0_DOMAIN}
clientId={process.env.AUTH0_CLIENTID}
redirectUri={window.location.origin + '/user'}
onRedirectCallback={onRedirectCallback}
>
{element}
</Auth0Provider>
);
};
// protectedpage.js
import React from 'react';
import { withAuthenticationRequired } from '#auth0/auth0-react';
const ProtectedPage = () => {
return (
<div>
Protected Page
</div>
);
};
export default withAuthenticationRequired(ProtectedPage);
// auth0 Application URIs
Allowed Callback URLs
http://localhost:8000/user
I'm not sure about your full implementation but to me, the fact that it gets stuck in an infinite loop could be related to the fact that you are replacing the history by removing the last visited page in:
navigate(appState?.returnTo || '/', { replace: true });
In addition, the callback is receiving an appState otherwise, it makes the history replacing but you are never providing it at (onRedirectCallback={onRedirectCallback}):
// gatsby-browser.js
import React from 'react';
import { Auth0Provider } from '#auth0/auth0-react';
import { navigate } from 'gatsby';
const onRedirectCallback = (appState) => {
navigate(appState?.returnTo || '/', { replace: true });
};
export const wrapRootElement = ({ element }) => {
return (
<Auth0Provider
domain={process.env.AUTH0_DOMAIN}
clientId={process.env.AUTH0_CLIENTID}
redirectUri={window.location.origin + '/user'}
onRedirectCallback={onRedirectCallback} //<-- here you are not providing an appState
>
{element}
</Auth0Provider>
);
};

How to onRowClick redirected to another page with mui-datatables npm package?

I have a react app that uses package mui-datatables. I want to be redirected to "/edit-form" onRowClick, but it didn't work (nothing happens, no errors either).
import React, { Component } from "react";
import { Link as RouterLink } from "react-router-dom";
import Link from "#material-ui/core/Link";
import MUIDataTable from "mui-datatables";
class DataTable extends Component {
state={...}
redirectToForm = props => <RouterLink to="/edit-form" {...props}/>
render() {
const options = {
onRowClick: rowData => this.redirectToForm(rowData)
};
return (
<Link
color="secondary"
className={classes.button}
component={this.goToDetailedTable}
>
Detail
</Link>
<MUIDataTable
title={title}
columns={value.state.columnName}
data={value.state.rowData}
options={options}
/>
)
}
When I console.log(rowData), it did print out the row data:
const options = {
onRowClick: rowData => console.log(rowData)
};
Instead of using <Link/> try calling history from the history package and then just history.push('edit/form').

Using mongodb-stitch library in Angular 4

Im been trying the MongoDB Stitch service in Angular, so far Im able to use the service. However, the only way I could connect to the service is by including the js library hosted in AWS on the html page.
There is a mongodb-stitch npm package available and there are sample pages on mongodb tutorial on how to use it. But this is a pure JS library (no TS support) and I have tried several ways (using require, installing typings of the lib (not available), using #types) to no avail.
Anyone tried this on Ng4? Would love to have the steps you did to use the 'mongodb-stitch' package the create a service.
The other answer suggests instantiating a new instance of StitchClient which is something that MongoDB have explicitly advised against in the Official API Documentation - and with reason, since there is a factory method available for that purpose. So, (after installing mongodb-stitch), the following code would help you get started in component.ts
import { Component, OnInit } from "#angular/core";
import { StitchClientFactory } from "mongodb-stitch";
let appId = 'authapp-****';
#Component({
selector: "app-mongo-auth",
templateUrl: "./mongo-auth.component.html",
styleUrls: ["./mongo-auth.component.css"]
})
export class MongoAuthComponent implements OnInit {
mClient;
ngOnInit() {
this.mClient = StitchClientFactory.create(appId);
}
And you can then use this for whatever purpose you want, such as for implementing sign-in with Google
gLogin(){
this.mClient.then(stitchClient => {
stitchClient.authenticate("google");
})
not sure whether the question is still relevant considering it was asked two months ago but anyway...
As you pointed out you can use
npm install --save mongodb-stitch
to install the package and since there is no TS binding you can declare the stitch library as any
For example:
declare var stitch: any;
export class MyService implements OnInit {
db;
client;
ngOnInit() {
this.client = new stitch.StitchClient('<check the stitch app page for proper value>');
this.db = this.client.service('mongodb', 'mongodb-atlas').db('<the db name goes here>');
this.client.login();
}
save() {
this.db.collection('<collection name>').insertOne({key : 'value'}).then(() => console.log("All done"));
}
}
the previous answers are functional, but i wanna share a example using a service injectable.
service.ts
import { Injectable } from '#angular/core';
import { Jsonp, URLSearchParams } from '#angular/http';
import { StitchClientFactory } from "mongodb-stitch";
import 'rxjs/add/operator/map';
#Injectable()
export class Service {
constructor(private jsonp: Jsonp) { }
client;
connect(){
this.client = new StitchClientFactory.create("App ID"); // Slitch apps > Clients > App ID
this.client.then(stitchClient => stitchClient.login())
.then((stitchClient) => console.log('logged in as: ' + stitchClient))
.catch(e => console.log('error: ', e));
}
all() {
this.connect();
return this.client.then(stitchClient => {
let db = stitchClient.service('mongodb', 'mongodb-atlas').db("database Name"); // Slitch apps > mongodb-atlas > Name database.Collection
let itemsCollection = db.collection('name collection'); // Slitch apps > mongodb-atlas > Name database.Collection
console.log(itemsCollection.find().execute());
return itemsCollection.find().execute();
})
.then(result => {return result})
.catch(e => console.log('error: ', e));
}
}
after make the previous file, you must create a module to receive the data, so:
module.ts
import { Component, OnInit, Injectable } from '#angular/core';
import { Observable } from 'rxjs/Observable';
import { StitchClientFactory } from "mongodb-stitch";
import { Service } from 'service'; // previous code
declare var stitch: any;
#Component({
template: '
<ul class="demo-list-icon mdl-list">
<li class="mdl-list__item" *ngFor="let item of data | async">
<span class="mdl-list__item-primary-content">
<i class="material-icons mdl-list__item-icon">{{propiedad.nombre}}</i>
</span>
</li>
</ul>
'
})
export class MainComponent implements OnInit {
data: Observable<[]>;
constructor(private Service: service) {
}
ngOnInit() {
this.propiedades = this.Service.all();
}
}
important, you don´t must forget to add service on module.ts intitial declarations.
mongodb Atlas
mongodb-stitch vía NPM
Documentation mongoDB Stitch.
Sure!

Firestack: firestack.auth.signInWithProvider('facebook', token, '') not firing

I wouldn't consider myself a bad developer, but 2 days into trying to get facebook login working with react native and firebase is making me think otherwise!
I have started again from scratch and am trying to implement react-native-firestack. Unfortunately I have hit a road block just trying to get the package setup.
The firestack events seem to work fine (e.g. console.logs from firestack.auth.getCurrentUser() seem to work fine - in that they fire).
Unfortunately the signInWithProvider event doesn't seem to fire. the console.log()s just before it fire, with the correct data being passed. I am hoping I have just missed some little detail, I have tried to copy all the code directly from the relevant tutorials from react-native-firestack and react-native-facebook-login (the login one looks to be running well).
See below for my code:
import React, { Component } from 'react';
import {FBLogin, FBLoginManager} from 'react-native-facebook-login';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';
import Firestack from 'react-native-firestack';
import FBLoginView from './src/FBLoginView';
export default class appTest extends Component {
render() {
const firestack = new Firestack();
firestack.auth.listenForAuth((evt) => {
if (!evt.authenticated) {
// There was an error or there is no user
console.log(evt.error);
} else {
// evt.user contains the user details
console.log('User details', evt.user);
}
})
.then(() => console.log('Listening for authentication changes'));
return (
<View style={styles.container}>
<FBLogin
buttonView={<FBLoginView />}
ref={(fbLogin) => { this.fbLogin = fbLogin }}
loginBehavior={FBLoginManager.LoginBehaviors.Native}
permissions={["email","user_friends"]}
onLogin={function(data){
console.log("Logged in!");
let token = data.credentials.token;
firestack.auth.signInWithProvider('facebook', token, '')
.then((user) => {
console.log(user)
}).catch((err) => {
console.error('User signin error', err);
});
}}
onLoginFound={function(e){console.log(e)}}
onLoginNotFound={function(e){console.log(e)}}
onLogout={function(e){console.log(e)}}
onCancel={function(e){console.log(e)}}
onPermissionsMissing={function(e){console.log(e)}}
/>
</View>
);
}
}
AppRegistry.registerComponent('appTest', () => appTest);