React router not redirect on the exact url - url

I am building an web application in which react-router is used. When i hit the url localhost:8080/user it works fine. When i hit localhost:8080/user/login it not works and console show unexpected tokken > what does it means? I could not understand the problem.
One more thing in this line of code when i changed to any other class then also its not working .
Routes.js
import React from 'react';
import UserBase from './UserBase.js';
import Dashboard from './Dashboard.js';
import Login from './Login.js';
// var ReactRouter = require('react-router');
// var Router = ReactRouter.Router;
// var Route = ReactRouter.Route;
import { Router, Route, IndexRoute, Link, IndexLink, browserHistory } from 'react-router'
var Routes = (
<Router history={browserHistory}>
<Route path="/" component={Login}/>
<Route path="user" component={UserBase}>
<IndexRoute component={Dashboard} />
<Route path="login" component={Login}/>
</Route>
</Router>
);
module.exports = Routes;
Login.js
import React from 'react';
class Login extends React.Component{
constructor(){
super();
}
render(){
return (
<div className="login">
<a className="hiddenanchor" id="signup"></a>
<a className="hiddenanchor" id="signin"></a>
<div className="login_wrapper">
<div className="animate form login_form">
<section className="login_content">
<form>
<h1>Login Form</h1>
</form>
</section>
</div>
<div id="register" className="animate form registration_form">
<section className="login_content">
<form>
<h1>Create Account</h1>
</form>
</section>
</div>
</div>
</div>
);
}
}
export default Login;
Routes js is working fine if I remove 'history={browserHistory}' means that if I use ugly url i.e. used with #. If I hit http://localhost:8080/#/user/login?_k=jtorvg is working fine then what will be the issue?
I use node server and express package to serve for every request.
var app = express();
app.use('/', express.static(path.join(__dirname, 'public')));
app.get('*', function(req, res) {
res.sendFile(path.join(__dirname + '/public/index.html'));
});
webpack.config.js
module.exports = {
entry: "./app/components/EntryPoint.js",
output: {
filename:"public/bundle.js"
},
module : {
loaders: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel',
query: {
presets: ['react', 'es2015']
}
}
]
}
};

Yes. I got the answer after struggling of hours a very small mistake. At index page bundle.js script path has to be changed for the url like localhost:8080/user/dashboard.
Just add <script src="/bundle.js" /> instead of <script src="bundle.js" />

Related

Images not loading on page change using Link in NextJS

This is hard to explain without uploading my full project likely, but here goes. I think I've narrowed it down to some combination of getInitialProps() and getStaticProps(). When I use next/link to change pages images are not being loaded. If I browse directly to the page images will load fine. Project is fairly simple with only 2 pages, index.js and [slug].js. Here's both:
index.js
import React from 'react';
import Layout from '../components/layout';
import Seo from '../components/seo';
import Hero from '../components/hero';
import Forcast from '../components/forcast';
import { fetchAPI } from '../lib/api';
import ReactMarkdown from 'react-markdown';
const Home = ({ pages, homepage }) => {
return (
<Layout pages={pages}>
<Seo seo={homepage.seo} />
<Hero hero={homepage.hero} />
<Forcast />
<main className='main-content'>
<div className='fullwidth-block'>
<div className='container'>
<div className='post single'>
<div className='entry-content'>
<ReactMarkdown
source={homepage.Content}
escapeHtml={false}
transformImageUri={uri =>
uri.startsWith('http') ? uri : `${process.env.REACT_APP_IMAGE_BASE_URL}/${uri}`
}
/>
</div>
</div>
</div>
</div>
</main>
</Layout>
);
};
export async function getStaticProps() {
// Run API calls in parallel
const [pages, homepage] = await Promise.all([
fetchAPI('/pages'),
fetchAPI('/homepage'),
]);
return {
props: { pages, homepage },
revalidate: 1,
};
}
export default Home;
[slug].js
import ReactMarkdown from 'react-markdown';
import Layout from '../components/layout';
import Seo from '../components/seo';
import { fetchAPI } from '../lib/api';
const Page = ({ page, pages }) => {
const seo = {
metaTitle: page.Title,
metaDescription: page.seo.metaDescription,
shareImage: page.seo.shareImage,
}
return (
<Layout pages={pages}>
<Seo seo={page.seo} />
<main className='main-content'>
<div className='container'>
<div className='breadcrumb'>
</div>
</div>
<div className='fullwidth-block'>
<div className='container'>
<div className='row'>
<div className='content col-md-8'>
<div className='post single'>
<h2 className='entry-title'>{page.Title}</h2>
<ReactMarkdown
source={page.Content}
escapeHtml={false}
transformImageUri={uri =>
uri.startsWith('http') ? uri : `${process.env.REACT_APP_IMAGE_BASE_URL}${uri}`
}
/>
</div>
</div>
</div>
</div>
</div>
</main>
</Layout>
);
};
export async function getStaticPaths() {
const pages = await fetchAPI('/pages');
return {
paths: pages.map((page) => ({
params: {
slug: page.slug,
},
})),
fallback: false,
};
}
export async function getStaticProps({ params }) {
const pages = await fetchAPI(
`/pages?slug=${params.slug}`
);
return {
props: { page: pages[0], pages },
revalidate: 1,
};
}
export default Page;
This might also be a Strapi issue though I'm not sure.
The issue happens because the REACT_APP_IMAGE_BASE_URL is not exposed to the browser, and only available on the server.
To have it exposed to the browser you'll need to add the NEXT_PUBLIC_ prefix to it.
# .env.development
NEXT_PUBLIC_REACT_APP_IMAGE_BASE_URL=http://localhost:1337
Then in your code reference it using process.env.NEXT_PUBLIC_REACT_APP_IMAGE_BASE_URL.

Having lots of trouble with React and Redux setup and props

I'm building a Dashboard style app that would show data service outages. The backend is Rails 6 and I'm using React/Redux in the frontend (within Rails). I'm having lots of trouble (due to my greenness in Redux) with getting the data into the front end and mapping state to props. Would love for someone to look at my app and see where I'm going wrong. It seems like I'm also having issues with Lexical behaviour as well.
Here is the top of the app:
import React from 'react';
import { render } from 'react-dom'
import Dashboard from './Dashboard';
import { Provider } from "react-redux";
import { createStore, applyMiddleware, compose } from 'redux'; // we get our store from redux library and we need middleware to wire up Thunk
import thunk from 'redux-thunk';
import reducers from './reducers/rootReducer';
import "bootstrap/dist/css/bootstrap.css";
import "bootstrap/dist/css/bootstrap.min.css";
const storeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(reducers, storeEnhancers(applyMiddleware(thunk)));
// this is how you hook up
store.subscribe(() => {
console.log('the new state is', store.getState());
console.log('----------');
});
render(
<Provider store={store}>
<Dashboard />
</Provider>,
document.body.appendChild(document.createElement('div')),
)
This is the top visible component Dashboard.js
import React, { Component } from "react";
import RecurringOutagesContainer from "./containers/RecurringOutagesContainer";
import FutureOutagesContainer from "./containers/FutureOutagesContainer";
import CurrentOutagesContainer from "./containers/CurrentOutagesContainer";
import CreateModalComponent from "./components/CreateModalComponent";
import { Container, Row, Col, Image } from "react-bootstrap";
import { getFutureOutages } from "./actions/fetchFutureOutagesAction";
import { getRecurringOutages } from "./actions/fetchRecurringOutagesAction";
import { getServices } from "./actions/fetchServicesAction";
import { connect } from 'react-redux';
class Dashboard extends Component {
state = {
services: [],
outages: [],
showModal: false
};
componentDidMount() {
this.props.getFutureOutages()
this.props.getRecurringOutages()
this.props.getServices()
}
render() {
console.log(this.props)
return (
<div>
<Container>
<Row>
<Col sm={1}>
<img
src={require("./public/logo-2-dashboard.png")}
alt="logo"
id="logo"
></img>
</Col>
<Col md={8}></Col>
</Row>
</Container>
<div className="container">
<div className="d-flex justify-content-md-end bd-highlight">
</div>
</div>
<div className="d-flex justify-content-center bd-highlight dashboard">
<div className="d-flex justify-content-start bd-highlight">
<div className="d-fliex pastOutages">
<h4>Past Outages</h4>
</div>
</div>
<div className="d-flex justify-content-center bd-highlight">
<div className="d-fliex currentOutages">
<h4>Current Outages</h4>
<div className="container">
<div className="col-12">
<CurrentOutagesContainer currentOutages={this.props.services} />
</div>
</div>
</div>
</div>
<div className="d-flex align-items-center flex-column bd-highlight">
<div className="d-fliex justify-content-center">
<h4>Future Outages</h4>
<div className="container" id="futureOutages">
<div className="col-12">
<FutureOutagesContainer futureOutages={this.props.futureOutages} />
</div>
</div>
<h4>Recurring Outages</h4>
<div className="container" id="recurringOutages">
<div className="col-12">
<RecurringOutagesContainer recurringOutages={this.props.recurringOutages} />
</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
const mapStateToProps = state => {
return {
futureOutages: state.futureOutages,
recurringOutages: state.recurringOutages,
services: state.services
}
};
const mapDispatchToProps = dispatch => {
return {
getFutureOutages: () => dispatch(getFutureOutages()),
getRecurringOutages: () => dispatch(getRecurringOutages()),
getServices: () => dispatch(getServices())
};
};
export default connect(mapStateToProps, mapDispatchToProps)(Dashboard); // this connects Dashboard to store
Here is one example of an action file:
\\ fetchFutureOutagesAction.js
import axios from 'axios';
export const getFutureOutages = () => dispatch => {
axios.get("/future_outages")
.then(res => {
const futureOutages = res.data;
dispatch({ type: 'FUTURE_OUTAGES', payload: futureOutages });
})
.catch(res => console.log(res.errors));
};
I have a rootReducer like so:
import { combineReducers } from 'redux';
import { futureOutagesReducer } from './futureOutagesReducer';
import { recurringOutagesReducer } from './recurringOutagesReducer';
import { servicesReducer } from './servicesReducer';
export default combineReducers({
futureOutages: futureOutagesReducer,
recurringOutages: recurringOutagesReducer,
services: servicesReducer
});
and here is an example of a reducer file:
const initialState = {
futureOutages: []
}
export const futureOutagesReducer = (state = initialState, action) => {
switch (action.type) {
case 'FUTURE_OUTAGES':
return { futureOutages: [...state.futureOutages, action.payload] };
default:
return state;
}
}
The errors are occuring in the container files that I pass props down to from `Dashboard.jsx':
import React from "react";
import FutureOutagesComponent from "../components/FutureOutagesComponent"
const FutureOutagesContainer = props => {
return (
<div>
{props.futureOutages && props.futureOutages.map((futureOutage, idx) => (
<FutureOutagesComponent key={idx} futureOutage={futureOutage} />
))
}
</div>
)
};
export default FutureOutagesContainer;
When I start ./bin/webpack-dev-server.js, here is a snapshot of errors in console I'm getting:
So clearly the props are not being passed down correctly. Can someone give me some pointers on implementing this better? I had everything working with just a React app but really want to have more flexibility accessing state through out the app.
Based on your reducer, I think you will need to access future outages like this.
const mapStateToProps = state => {
return {
futureOutages: state.futureOutages.futureOutages
}
};
The name of your reducer is futureOutages and it also has a property by the same name whose value is an array.
export default combineReducers({
// state.futureOutages
futureOutages: futureOutagesReducer,
...
})
Accessing state.futureOutages will give you an object which is the full piece of state for that reducer from the Refux store. But you want a specific property. Because it's an object and not array, Array.prototype.map is not a func. HTH.

Angular Dart 2 - querySelect returning null

I'm trying to set up a drag&drop component to upload multiple files. However, when I attempt to access elements on the DOM with the querySelector method, I end up with null.
I've tried to implement the AfterViewInit class to no avail. Here's my current dart code for the component:
import 'dart:html';
import 'package:dnd/dnd.dart';
import 'package:angular/angular.dart';
#Component(
selector: 'upload',
templateUrl: 'upload.html',
styleUrls: [
'upload.css'
]
)
class Upload implements AfterViewInit {
#override
void ngAfterViewInit() {
// TODO: implement ngOnInit
Draggable d = new Draggable(document.querySelectorAll('.page'), avatarHandler : new AvatarHandler.clone());
var del = document.querySelector('.upload');
print(del); //prints null
Dropzone dropzone = new Dropzone(document.querySelector('.upload')); //throws an error, as it doesn't expect null.
dropzone.onDrop.listen((DropzoneEvent event){
print(event);
});
}
}
Also, my upload.html file is as follows:
<div class="center-me page" uk-grid>
<div class="uk-align-center text-align-center">
<h2 class="text-align-center" >Upload a file</h2>
<div class="upload uk-placeholder uk-text-center">
<span uk-icon="icon: cloud-upload"></span>
<span class="uk-text-middle">Attach binaries by dropping them here or</span>
<div uk-form-custom>
<input type="file" multiple>
<span class="uk-link">selecting one</span>
</div>
</div>
<progress id="progressbar" class="uk-progress" value="0" max="100" hidden></progress>
</div>
</div>
Thanks in advance.
So this looks like it should work. I wouldn't actually suggest doing it this way as it will get any element with an upload class which if you reuse the component will be a lot.
I would suggest using the ViewChild syntax instead
class Upload implements AfterViewInit {
#ViewChild('upload')
void uploadElm(HtmlElement elm) {
Dropzone dropzone = new Dropzone(elm);
dropzone.onDrop.listen((DropzoneEvent event){
print(event);
});
}
}
In the template:
<div class="uk-placeholder uk-text-center" #upload>
That said you shouldn't be getting null from the querySelect, but from the code you have shown I'm not sure why.

How to get the url to insert as a data with Redux Form?

I was able to get the url in the attachment field but for the redux form it was empty, how is possible to pass the value of the url to the redux form? Below is the code and the screenshot:
<div className="FileUpload">
<Dropzone
onDrop={this.onImageDrop.bind(this)}
multiple={false}
accept="image/*">
<div>Drop an image or click to select a file to upload.</div>
</Dropzone>
</div>
<div className="form-group">
<label htmlFor="attachment">Attachment:</label><br />
<input className="form-control" focus placeholder="attachment" type="text" name="attachment" ref="attachment" value={this.state.uploadedFileCloudinaryUrl} />
{this.state.uploadedFileCloudinaryUrl === '' ? null :
<div>
<p>{this.state.uploadedFile.name}</p>
<img src={this.state.uploadedFileCloudinaryUrl} alt="" />
</div>}
</div>
<div className="ui small image">
<img src={this.props.workrequest.attachment} alt="" />
</div>
the url in the attachemnt field
The first one is using the React Dropzone to get the url but for the Redux Form it was empty. May I know how to do that to get the url inserts at Redux Form here? Thank you
import React from 'React';
import { connect } from 'react-redux';
import { change, reduxForm } from 'redux-form';
import Dropzone from 'react-dropzone';
class UploadForm extends React.Component {
onDrop = (accepted) => {
if (!accepted.length) return;
// start uploading
this.setState({ isUploading: true });
const formData = new FormData();
formData.append('file', accepted[0]);
axios.post('upload', formData).then(
(res) => {
this.props.dispatch(change('uploadForm', 'url', res.url));
this.setState({ isUploading: false });
},
() => {
this.setState({ isUploading: false });
}
);
};
render() {
return (
<form>
<Dropzone onDrop={this.onDrop} />
</form>
);
}
}
export default connect()(
reduxForm({
form: 'uploadForm',
initialValues: {
url: ''
}
})(UploadForm)
);
Please use this.
Actually, you must use Field component from Redux-form.
Other wise, you can change form values using dispatch and change action creator.
import { Field, change } from 'redux-form';
this.props.dispatch(change('uploadForm', 'url', this.state.url));

Pass data from Rails template to Vue Instance

I've been trying to pass data from my Rails view to the Vue component as described here
Everything works much as expected, but I'm rather stumped as to how to access the data that I'm passing in via props. Not appearing in the Vue developer tools anywhere and I'm not able to find it by fiddling with/inside the Vue object.
Could someone point me in the right direction. I'm fairly green with Vue, so struggling to even know what to search for :/
show.html.erb
<%= javascript_pack_tag 'test_vue' %>
<%= stylesheet_pack_tag 'test_vue' %>
<%= content_tag :div, id: "test", data: {
message: "this wont!",
name: "nor will this!" }.to_json do %>
<% end %>
test.vue
<template>
<div id="app">
<p>{{test}}{{message}}{{name}}</p>
</div>
</template>
<script>
export default {
data: function () {
return {
test: 'This will display',
}
}
}
</script>
<style>
</style>
test_vue.js
import Vue from 'vue'
import Test from './test.vue'
document.addEventListener('DOMContentLoaded', () => {
const node = document.getElementById('test')
const props = JSON.parse(node.getAttribute('data'))
new Vue({
render: h => h(Test, { props })
}).$mount('#test');
})
Looks like all you need to do is declare the properties in your component:
<template>
<div id="app">
<p>{{test}}{{message}}{{name}}</p>
</div>
</template>
<script>
export default {
props: ["message","name"],
data: function () {
return {
test: 'This will display',
}
}
}
</script>
<style>
</style>
This would be the relevant documentation.
A child component needs to explicitly declare the props it expects to
receive using the props option

Resources