React- Button Onclick NOT rendering a file from file-system - On any click on the link Its alwasys rendering...
I am relatively new to React and certainly in this project I am missing something basic.
I have uploaded a small sample project with this functionality in codesandbox here . Although you will see error in codesandbox (because as of now dont think it supports node and mongo backend). Pushed the code there only to show whole project.
Here’s the project flow.
Its a full-stack project, and I have few files uploaded to the project’s file-system using node and mongodb in the /uploads directory. However my current issue is ONLY in the React front-end which is about rendering the uploaded files on click of a button. From the React front-end I am rendering those files by clicking on a button and then opening a Material-UI modal. So each time a user click on the "Download file" a Modal opens and inside that Modal I click on the "View File" button the relevant file should be rendered in a new tab.
But each time I am clicking on the view file, an uploaded file is indeed been rendered but always its the last file in the ‘images’ object.
Here’s my ../src/Components/FileUpload.js
which has Material-UI modal implemented. The handleClose function takes a single parameter fileLink
which is the link of the file that I am fetching from the images
object.
class FileUpload extends Component {
state = {
documents: ,
open: false
};
handleClickOpen = () => {
this.setState({ open: true });
};
handleClose = fileLink => {
this.setState({
open: false
});
window.open(`${fileLink}`, "_blank");
};
deleteDocument = id => {
axios.delete("/api/document/" + id).then(() => {
this.setState({
documents: this.state.documents.filter(document => document._id !== id)
});
});
};
componentDidMount() {
axios.get("/api/document").then(res => {
this.setState({ documents: res.data });
});
}
importAll = result => {
let images = {};
result.keys().map((item, index) => {
return (images[item.replace("./", "")] = result(item));
});
return images;
};
render() {
const webpackContext = require.context(
"../../uploads",
false,
/.(png|jpe?g|svg|pdf|doc|odt)$/
);
const images = this.importAll(webpackContext);
console.log(images);
return (
<div className="bg-success">
<Col xs="8">
<Card>
<CardHeader className="p-2 mb-2 bg-primary text-white" />
<CardBody>
<CardText>
<table className="table table-stripe">
<thead>
<tr>
<th>Document Id</th>
<th>Description</th>
</tr>
</thead>
<tbody>
{this.state.documents.map(document => (
<tr>
<td>{document.document_id}</td>
<td>{document.description}</td>
<td>
<Button onClick={this.handleClickOpen}>
Download file
</Button>
<Dialog
open={this.state.open}
onClose={this.handleClose}
aria-labelledby="form-dialog-title"
>
<DialogTitle id="form-dialog-title">
Required Information
</DialogTitle>
<DialogContent>
<DialogContentText>
Update these info to download the file
</DialogContentText>
<TextField
autoFocus
margin="dense"
id="name"
label="Email Address"
type="email"
fullWidth
/>
</DialogContent>
<DialogActions>
<Button
onClick={this.handleClose}
color="primary"
>
Cancel
</Button>
<Button
onClick={this.handleClose.bind(
this,
images[`${document.path}`]
)}
color="primary"
>
Download file
</Button>
</DialogActions>
</Dialog>
</td>
<td>
<Link
to={`/api/document/edit/${document._id}`}
class="btn btn-success"
>
Edit Description
</Link>
</td>
<td>
<button
onClick={this.deleteDocument.bind(
this,
document._id
)}
className="btn btn-danger"
>
Delete
</button>
</td>
</tr>
))}
</tbody>
</table>
</CardText>
</CardBody>
</Card>
</Col>
```
So, on click of the Button I am doing a
onClick={this.handleClose.bind}
passing to the handleClose
funtion the parameter of the filepath link ( i.e. the link with which I should be able to render that file )
And I am picking up the file link from an object that I have created in this compoenent itself with Webpack’s require.context and saving in the variable named images with
const images = this.importAll(webpackContext);
But each time I am clicking on the view file, an uploaded file is indeed been rendered but always its the last file in the ‘images’ object.
The handleClose
function is not picking up the other files in the images object.
reactjs material-ui
add a comment |
I am relatively new to React and certainly in this project I am missing something basic.
I have uploaded a small sample project with this functionality in codesandbox here . Although you will see error in codesandbox (because as of now dont think it supports node and mongo backend). Pushed the code there only to show whole project.
Here’s the project flow.
Its a full-stack project, and I have few files uploaded to the project’s file-system using node and mongodb in the /uploads directory. However my current issue is ONLY in the React front-end which is about rendering the uploaded files on click of a button. From the React front-end I am rendering those files by clicking on a button and then opening a Material-UI modal. So each time a user click on the "Download file" a Modal opens and inside that Modal I click on the "View File" button the relevant file should be rendered in a new tab.
But each time I am clicking on the view file, an uploaded file is indeed been rendered but always its the last file in the ‘images’ object.
Here’s my ../src/Components/FileUpload.js
which has Material-UI modal implemented. The handleClose function takes a single parameter fileLink
which is the link of the file that I am fetching from the images
object.
class FileUpload extends Component {
state = {
documents: ,
open: false
};
handleClickOpen = () => {
this.setState({ open: true });
};
handleClose = fileLink => {
this.setState({
open: false
});
window.open(`${fileLink}`, "_blank");
};
deleteDocument = id => {
axios.delete("/api/document/" + id).then(() => {
this.setState({
documents: this.state.documents.filter(document => document._id !== id)
});
});
};
componentDidMount() {
axios.get("/api/document").then(res => {
this.setState({ documents: res.data });
});
}
importAll = result => {
let images = {};
result.keys().map((item, index) => {
return (images[item.replace("./", "")] = result(item));
});
return images;
};
render() {
const webpackContext = require.context(
"../../uploads",
false,
/.(png|jpe?g|svg|pdf|doc|odt)$/
);
const images = this.importAll(webpackContext);
console.log(images);
return (
<div className="bg-success">
<Col xs="8">
<Card>
<CardHeader className="p-2 mb-2 bg-primary text-white" />
<CardBody>
<CardText>
<table className="table table-stripe">
<thead>
<tr>
<th>Document Id</th>
<th>Description</th>
</tr>
</thead>
<tbody>
{this.state.documents.map(document => (
<tr>
<td>{document.document_id}</td>
<td>{document.description}</td>
<td>
<Button onClick={this.handleClickOpen}>
Download file
</Button>
<Dialog
open={this.state.open}
onClose={this.handleClose}
aria-labelledby="form-dialog-title"
>
<DialogTitle id="form-dialog-title">
Required Information
</DialogTitle>
<DialogContent>
<DialogContentText>
Update these info to download the file
</DialogContentText>
<TextField
autoFocus
margin="dense"
id="name"
label="Email Address"
type="email"
fullWidth
/>
</DialogContent>
<DialogActions>
<Button
onClick={this.handleClose}
color="primary"
>
Cancel
</Button>
<Button
onClick={this.handleClose.bind(
this,
images[`${document.path}`]
)}
color="primary"
>
Download file
</Button>
</DialogActions>
</Dialog>
</td>
<td>
<Link
to={`/api/document/edit/${document._id}`}
class="btn btn-success"
>
Edit Description
</Link>
</td>
<td>
<button
onClick={this.deleteDocument.bind(
this,
document._id
)}
className="btn btn-danger"
>
Delete
</button>
</td>
</tr>
))}
</tbody>
</table>
</CardText>
</CardBody>
</Card>
</Col>
```
So, on click of the Button I am doing a
onClick={this.handleClose.bind}
passing to the handleClose
funtion the parameter of the filepath link ( i.e. the link with which I should be able to render that file )
And I am picking up the file link from an object that I have created in this compoenent itself with Webpack’s require.context and saving in the variable named images with
const images = this.importAll(webpackContext);
But each time I am clicking on the view file, an uploaded file is indeed been rendered but always its the last file in the ‘images’ object.
The handleClose
function is not picking up the other files in the images object.
reactjs material-ui
It's broken palrequire.context is not a function
– giwiro
Nov 13 '18 at 16:41
codesandbox will not run, I pushed the code there just to show my whole project - to see the full project you have to download to your machine and then dosudo service mongod start
and then the following regular commands -npm install
-npm run dev
– Rohan_Paul
Nov 13 '18 at 16:45
How about using an arrow function instead of using bind here?
– VivekN
Nov 13 '18 at 21:35
add a comment |
I am relatively new to React and certainly in this project I am missing something basic.
I have uploaded a small sample project with this functionality in codesandbox here . Although you will see error in codesandbox (because as of now dont think it supports node and mongo backend). Pushed the code there only to show whole project.
Here’s the project flow.
Its a full-stack project, and I have few files uploaded to the project’s file-system using node and mongodb in the /uploads directory. However my current issue is ONLY in the React front-end which is about rendering the uploaded files on click of a button. From the React front-end I am rendering those files by clicking on a button and then opening a Material-UI modal. So each time a user click on the "Download file" a Modal opens and inside that Modal I click on the "View File" button the relevant file should be rendered in a new tab.
But each time I am clicking on the view file, an uploaded file is indeed been rendered but always its the last file in the ‘images’ object.
Here’s my ../src/Components/FileUpload.js
which has Material-UI modal implemented. The handleClose function takes a single parameter fileLink
which is the link of the file that I am fetching from the images
object.
class FileUpload extends Component {
state = {
documents: ,
open: false
};
handleClickOpen = () => {
this.setState({ open: true });
};
handleClose = fileLink => {
this.setState({
open: false
});
window.open(`${fileLink}`, "_blank");
};
deleteDocument = id => {
axios.delete("/api/document/" + id).then(() => {
this.setState({
documents: this.state.documents.filter(document => document._id !== id)
});
});
};
componentDidMount() {
axios.get("/api/document").then(res => {
this.setState({ documents: res.data });
});
}
importAll = result => {
let images = {};
result.keys().map((item, index) => {
return (images[item.replace("./", "")] = result(item));
});
return images;
};
render() {
const webpackContext = require.context(
"../../uploads",
false,
/.(png|jpe?g|svg|pdf|doc|odt)$/
);
const images = this.importAll(webpackContext);
console.log(images);
return (
<div className="bg-success">
<Col xs="8">
<Card>
<CardHeader className="p-2 mb-2 bg-primary text-white" />
<CardBody>
<CardText>
<table className="table table-stripe">
<thead>
<tr>
<th>Document Id</th>
<th>Description</th>
</tr>
</thead>
<tbody>
{this.state.documents.map(document => (
<tr>
<td>{document.document_id}</td>
<td>{document.description}</td>
<td>
<Button onClick={this.handleClickOpen}>
Download file
</Button>
<Dialog
open={this.state.open}
onClose={this.handleClose}
aria-labelledby="form-dialog-title"
>
<DialogTitle id="form-dialog-title">
Required Information
</DialogTitle>
<DialogContent>
<DialogContentText>
Update these info to download the file
</DialogContentText>
<TextField
autoFocus
margin="dense"
id="name"
label="Email Address"
type="email"
fullWidth
/>
</DialogContent>
<DialogActions>
<Button
onClick={this.handleClose}
color="primary"
>
Cancel
</Button>
<Button
onClick={this.handleClose.bind(
this,
images[`${document.path}`]
)}
color="primary"
>
Download file
</Button>
</DialogActions>
</Dialog>
</td>
<td>
<Link
to={`/api/document/edit/${document._id}`}
class="btn btn-success"
>
Edit Description
</Link>
</td>
<td>
<button
onClick={this.deleteDocument.bind(
this,
document._id
)}
className="btn btn-danger"
>
Delete
</button>
</td>
</tr>
))}
</tbody>
</table>
</CardText>
</CardBody>
</Card>
</Col>
```
So, on click of the Button I am doing a
onClick={this.handleClose.bind}
passing to the handleClose
funtion the parameter of the filepath link ( i.e. the link with which I should be able to render that file )
And I am picking up the file link from an object that I have created in this compoenent itself with Webpack’s require.context and saving in the variable named images with
const images = this.importAll(webpackContext);
But each time I am clicking on the view file, an uploaded file is indeed been rendered but always its the last file in the ‘images’ object.
The handleClose
function is not picking up the other files in the images object.
reactjs material-ui
I am relatively new to React and certainly in this project I am missing something basic.
I have uploaded a small sample project with this functionality in codesandbox here . Although you will see error in codesandbox (because as of now dont think it supports node and mongo backend). Pushed the code there only to show whole project.
Here’s the project flow.
Its a full-stack project, and I have few files uploaded to the project’s file-system using node and mongodb in the /uploads directory. However my current issue is ONLY in the React front-end which is about rendering the uploaded files on click of a button. From the React front-end I am rendering those files by clicking on a button and then opening a Material-UI modal. So each time a user click on the "Download file" a Modal opens and inside that Modal I click on the "View File" button the relevant file should be rendered in a new tab.
But each time I am clicking on the view file, an uploaded file is indeed been rendered but always its the last file in the ‘images’ object.
Here’s my ../src/Components/FileUpload.js
which has Material-UI modal implemented. The handleClose function takes a single parameter fileLink
which is the link of the file that I am fetching from the images
object.
class FileUpload extends Component {
state = {
documents: ,
open: false
};
handleClickOpen = () => {
this.setState({ open: true });
};
handleClose = fileLink => {
this.setState({
open: false
});
window.open(`${fileLink}`, "_blank");
};
deleteDocument = id => {
axios.delete("/api/document/" + id).then(() => {
this.setState({
documents: this.state.documents.filter(document => document._id !== id)
});
});
};
componentDidMount() {
axios.get("/api/document").then(res => {
this.setState({ documents: res.data });
});
}
importAll = result => {
let images = {};
result.keys().map((item, index) => {
return (images[item.replace("./", "")] = result(item));
});
return images;
};
render() {
const webpackContext = require.context(
"../../uploads",
false,
/.(png|jpe?g|svg|pdf|doc|odt)$/
);
const images = this.importAll(webpackContext);
console.log(images);
return (
<div className="bg-success">
<Col xs="8">
<Card>
<CardHeader className="p-2 mb-2 bg-primary text-white" />
<CardBody>
<CardText>
<table className="table table-stripe">
<thead>
<tr>
<th>Document Id</th>
<th>Description</th>
</tr>
</thead>
<tbody>
{this.state.documents.map(document => (
<tr>
<td>{document.document_id}</td>
<td>{document.description}</td>
<td>
<Button onClick={this.handleClickOpen}>
Download file
</Button>
<Dialog
open={this.state.open}
onClose={this.handleClose}
aria-labelledby="form-dialog-title"
>
<DialogTitle id="form-dialog-title">
Required Information
</DialogTitle>
<DialogContent>
<DialogContentText>
Update these info to download the file
</DialogContentText>
<TextField
autoFocus
margin="dense"
id="name"
label="Email Address"
type="email"
fullWidth
/>
</DialogContent>
<DialogActions>
<Button
onClick={this.handleClose}
color="primary"
>
Cancel
</Button>
<Button
onClick={this.handleClose.bind(
this,
images[`${document.path}`]
)}
color="primary"
>
Download file
</Button>
</DialogActions>
</Dialog>
</td>
<td>
<Link
to={`/api/document/edit/${document._id}`}
class="btn btn-success"
>
Edit Description
</Link>
</td>
<td>
<button
onClick={this.deleteDocument.bind(
this,
document._id
)}
className="btn btn-danger"
>
Delete
</button>
</td>
</tr>
))}
</tbody>
</table>
</CardText>
</CardBody>
</Card>
</Col>
```
So, on click of the Button I am doing a
onClick={this.handleClose.bind}
passing to the handleClose
funtion the parameter of the filepath link ( i.e. the link with which I should be able to render that file )
And I am picking up the file link from an object that I have created in this compoenent itself with Webpack’s require.context and saving in the variable named images with
const images = this.importAll(webpackContext);
But each time I am clicking on the view file, an uploaded file is indeed been rendered but always its the last file in the ‘images’ object.
The handleClose
function is not picking up the other files in the images object.
reactjs material-ui
reactjs material-ui
edited Nov 14 '18 at 4:23
Rohan_Paul
asked Nov 13 '18 at 16:05
Rohan_PaulRohan_Paul
7071015
7071015
It's broken palrequire.context is not a function
– giwiro
Nov 13 '18 at 16:41
codesandbox will not run, I pushed the code there just to show my whole project - to see the full project you have to download to your machine and then dosudo service mongod start
and then the following regular commands -npm install
-npm run dev
– Rohan_Paul
Nov 13 '18 at 16:45
How about using an arrow function instead of using bind here?
– VivekN
Nov 13 '18 at 21:35
add a comment |
It's broken palrequire.context is not a function
– giwiro
Nov 13 '18 at 16:41
codesandbox will not run, I pushed the code there just to show my whole project - to see the full project you have to download to your machine and then dosudo service mongod start
and then the following regular commands -npm install
-npm run dev
– Rohan_Paul
Nov 13 '18 at 16:45
How about using an arrow function instead of using bind here?
– VivekN
Nov 13 '18 at 21:35
It's broken pal
require.context is not a function
– giwiro
Nov 13 '18 at 16:41
It's broken pal
require.context is not a function
– giwiro
Nov 13 '18 at 16:41
codesandbox will not run, I pushed the code there just to show my whole project - to see the full project you have to download to your machine and then do
sudo service mongod start
and then the following regular commands - npm install
- npm run dev
– Rohan_Paul
Nov 13 '18 at 16:45
codesandbox will not run, I pushed the code there just to show my whole project - to see the full project you have to download to your machine and then do
sudo service mongod start
and then the following regular commands - npm install
- npm run dev
– Rohan_Paul
Nov 13 '18 at 16:45
How about using an arrow function instead of using bind here?
– VivekN
Nov 13 '18 at 21:35
How about using an arrow function instead of using bind here?
– VivekN
Nov 13 '18 at 21:35
add a comment |
1 Answer
1
active
oldest
votes
Answering my own question (in case it helps anybody else) -
The mistake I was making is this -
When passing data from my FileUpload.js
.map
function to the handleClose
funtion passing the fileLink to render, I was not implementing any way to hook into that particluar file referred by the link.
Corrected it by A) From FileUpload.js when clicking on the Button to Download/View file, now I am rendering a completely new component ( RenderFile.js
) which will take care of opening the Material-UI modal and rendering the correct link for viewing the file.
This is my updated FileUpload.js file
class FileUpload extends Component {
state = {
documents: ,
clicked: false,
textBeforeDownload: "View/Download"
};
launchRenderFileComp = () => {
this.setState({
clicked: true,
textBeforeDownload: ""
});
};
deleteDocument = id => {
axios.delete("/api/document/" + id).then(() => {
this.setState({
documents: this.state.documents.filter(document => document._id !== id)
});
});
};
componentDidMount() {
axios.get("/api/document").then(res => {
this.setState({ documents: res.data });
});
}
importAll = result => {
let images = {};
result.keys().map((item, index) => {
return (images[item.replace("./", "")] = result(item));
});
return images;
};
render() {
const { documents } = this.state;
const webpackContext = require.context(
"../../uploads",
false,
/.(png|jpe?g|svg|pdf|doc|odt)$/
);
const images = this.importAll(webpackContext);
return (
<div className="bg-success">
<Col xs="8">
<Card>
<CardHeader className="p-2 mb-2 bg-primary text-white" />
<CardBody>
<CardText>
<table className="table table-stripe">
<thead>
<tr>
<th>Document Id</th>
<th>Description</th>
</tr>
</thead>
<tbody>
{documents.map(document => (
<tr>
<td>{document.document_id}</td>
<td>{document.description}</td>
<td>
<Button onClick={this.launchRenderFileComp}>
{this.state.clicked ? (
<RenderFile linkForRender={document.path} />
) : null}
{this.state.textBeforeDownload}
</Button>
</td>
<td>
<Link
to={`/api/document/edit/${document._id}`}
class="btn btn-success"
>
Edit Description
</Link>
</td>
<td>
<button
onClick={this.deleteDocument.bind(
this,
document._id
)}
className="btn btn-danger"
>
Delete
</button>
</td>
</tr>
))}
</tbody>
</table>
</CardText>
</CardBody>
</Card>
</Col>
And this is the new RenderFile.js compoenent that will take care of both opening the modal and rendering the file.
import React, { Component } from "react";
import Button from "@material-ui/core/Button";
import TextField from "@material-ui/core/TextField";
import Dialog from "@material-ui/core/Dialog";
import DialogActions from "@material-ui/core/DialogActions";
import DialogContent from "@material-ui/core/DialogContent";
import DialogContentText from "@material-ui/core/DialogContentText";
import DialogTitle from "@material-ui/core/DialogTitle";
class RenderFile extends Component {
state = {
open: false
};
handleToggle = () => {
this.setState({
open: !this.state.open
});
};
handleClickOpen = () => {
this.setState({ open: true });
};
handleClose = file => {
// file = this.file;
this.setState({
open: false
});
window.open(`${file}`, "_blank");
};
handleCancel = () => {
this.setState({ open: false });
};
importAll = result => {
let images = {};
result.keys().map((item, index) => {
return (images[item.replace("./", "")] = result(item));
});
return images;
};
render() {
const webpackContext = require.context(
"../../uploads",
false,
/.(png|jpe?g|svg|pdf|doc|odt)$/
);
const images = this.importAll(webpackContext);
const { linkForRender } = this.props;
return (
<div>
<Button onClick={this.handleClickOpen}>Click to View File</Button>
<Dialog
open={this.state.open}
onClose={this.handleToggle}
aria-labelledby="form-dialog-title"
>
<DialogTitle id="form-dialog-title">Required Information</DialogTitle>
<DialogContent>
<DialogContentText>
Update these info to download the file
</DialogContentText>
<TextField
autoFocus
margin="dense"
id="name"
label="Email Address"
type="email"
fullWidth
/>
</DialogContent>
<DialogActions>
<Button onClick={this.handleCancel} color="primary">
Cancel
</Button>
<Button
onClick={this.handleClose.bind(this, images[`${linkForRender}`])}
color="primary"
>
View or Download File
</Button>
</DialogActions>
</Dialog>
</div>
);
}
}
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53284973%2freact-button-onclick-not-rendering-a-file-from-file-system-on-any-click-on-th%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Answering my own question (in case it helps anybody else) -
The mistake I was making is this -
When passing data from my FileUpload.js
.map
function to the handleClose
funtion passing the fileLink to render, I was not implementing any way to hook into that particluar file referred by the link.
Corrected it by A) From FileUpload.js when clicking on the Button to Download/View file, now I am rendering a completely new component ( RenderFile.js
) which will take care of opening the Material-UI modal and rendering the correct link for viewing the file.
This is my updated FileUpload.js file
class FileUpload extends Component {
state = {
documents: ,
clicked: false,
textBeforeDownload: "View/Download"
};
launchRenderFileComp = () => {
this.setState({
clicked: true,
textBeforeDownload: ""
});
};
deleteDocument = id => {
axios.delete("/api/document/" + id).then(() => {
this.setState({
documents: this.state.documents.filter(document => document._id !== id)
});
});
};
componentDidMount() {
axios.get("/api/document").then(res => {
this.setState({ documents: res.data });
});
}
importAll = result => {
let images = {};
result.keys().map((item, index) => {
return (images[item.replace("./", "")] = result(item));
});
return images;
};
render() {
const { documents } = this.state;
const webpackContext = require.context(
"../../uploads",
false,
/.(png|jpe?g|svg|pdf|doc|odt)$/
);
const images = this.importAll(webpackContext);
return (
<div className="bg-success">
<Col xs="8">
<Card>
<CardHeader className="p-2 mb-2 bg-primary text-white" />
<CardBody>
<CardText>
<table className="table table-stripe">
<thead>
<tr>
<th>Document Id</th>
<th>Description</th>
</tr>
</thead>
<tbody>
{documents.map(document => (
<tr>
<td>{document.document_id}</td>
<td>{document.description}</td>
<td>
<Button onClick={this.launchRenderFileComp}>
{this.state.clicked ? (
<RenderFile linkForRender={document.path} />
) : null}
{this.state.textBeforeDownload}
</Button>
</td>
<td>
<Link
to={`/api/document/edit/${document._id}`}
class="btn btn-success"
>
Edit Description
</Link>
</td>
<td>
<button
onClick={this.deleteDocument.bind(
this,
document._id
)}
className="btn btn-danger"
>
Delete
</button>
</td>
</tr>
))}
</tbody>
</table>
</CardText>
</CardBody>
</Card>
</Col>
And this is the new RenderFile.js compoenent that will take care of both opening the modal and rendering the file.
import React, { Component } from "react";
import Button from "@material-ui/core/Button";
import TextField from "@material-ui/core/TextField";
import Dialog from "@material-ui/core/Dialog";
import DialogActions from "@material-ui/core/DialogActions";
import DialogContent from "@material-ui/core/DialogContent";
import DialogContentText from "@material-ui/core/DialogContentText";
import DialogTitle from "@material-ui/core/DialogTitle";
class RenderFile extends Component {
state = {
open: false
};
handleToggle = () => {
this.setState({
open: !this.state.open
});
};
handleClickOpen = () => {
this.setState({ open: true });
};
handleClose = file => {
// file = this.file;
this.setState({
open: false
});
window.open(`${file}`, "_blank");
};
handleCancel = () => {
this.setState({ open: false });
};
importAll = result => {
let images = {};
result.keys().map((item, index) => {
return (images[item.replace("./", "")] = result(item));
});
return images;
};
render() {
const webpackContext = require.context(
"../../uploads",
false,
/.(png|jpe?g|svg|pdf|doc|odt)$/
);
const images = this.importAll(webpackContext);
const { linkForRender } = this.props;
return (
<div>
<Button onClick={this.handleClickOpen}>Click to View File</Button>
<Dialog
open={this.state.open}
onClose={this.handleToggle}
aria-labelledby="form-dialog-title"
>
<DialogTitle id="form-dialog-title">Required Information</DialogTitle>
<DialogContent>
<DialogContentText>
Update these info to download the file
</DialogContentText>
<TextField
autoFocus
margin="dense"
id="name"
label="Email Address"
type="email"
fullWidth
/>
</DialogContent>
<DialogActions>
<Button onClick={this.handleCancel} color="primary">
Cancel
</Button>
<Button
onClick={this.handleClose.bind(this, images[`${linkForRender}`])}
color="primary"
>
View or Download File
</Button>
</DialogActions>
</Dialog>
</div>
);
}
}
add a comment |
Answering my own question (in case it helps anybody else) -
The mistake I was making is this -
When passing data from my FileUpload.js
.map
function to the handleClose
funtion passing the fileLink to render, I was not implementing any way to hook into that particluar file referred by the link.
Corrected it by A) From FileUpload.js when clicking on the Button to Download/View file, now I am rendering a completely new component ( RenderFile.js
) which will take care of opening the Material-UI modal and rendering the correct link for viewing the file.
This is my updated FileUpload.js file
class FileUpload extends Component {
state = {
documents: ,
clicked: false,
textBeforeDownload: "View/Download"
};
launchRenderFileComp = () => {
this.setState({
clicked: true,
textBeforeDownload: ""
});
};
deleteDocument = id => {
axios.delete("/api/document/" + id).then(() => {
this.setState({
documents: this.state.documents.filter(document => document._id !== id)
});
});
};
componentDidMount() {
axios.get("/api/document").then(res => {
this.setState({ documents: res.data });
});
}
importAll = result => {
let images = {};
result.keys().map((item, index) => {
return (images[item.replace("./", "")] = result(item));
});
return images;
};
render() {
const { documents } = this.state;
const webpackContext = require.context(
"../../uploads",
false,
/.(png|jpe?g|svg|pdf|doc|odt)$/
);
const images = this.importAll(webpackContext);
return (
<div className="bg-success">
<Col xs="8">
<Card>
<CardHeader className="p-2 mb-2 bg-primary text-white" />
<CardBody>
<CardText>
<table className="table table-stripe">
<thead>
<tr>
<th>Document Id</th>
<th>Description</th>
</tr>
</thead>
<tbody>
{documents.map(document => (
<tr>
<td>{document.document_id}</td>
<td>{document.description}</td>
<td>
<Button onClick={this.launchRenderFileComp}>
{this.state.clicked ? (
<RenderFile linkForRender={document.path} />
) : null}
{this.state.textBeforeDownload}
</Button>
</td>
<td>
<Link
to={`/api/document/edit/${document._id}`}
class="btn btn-success"
>
Edit Description
</Link>
</td>
<td>
<button
onClick={this.deleteDocument.bind(
this,
document._id
)}
className="btn btn-danger"
>
Delete
</button>
</td>
</tr>
))}
</tbody>
</table>
</CardText>
</CardBody>
</Card>
</Col>
And this is the new RenderFile.js compoenent that will take care of both opening the modal and rendering the file.
import React, { Component } from "react";
import Button from "@material-ui/core/Button";
import TextField from "@material-ui/core/TextField";
import Dialog from "@material-ui/core/Dialog";
import DialogActions from "@material-ui/core/DialogActions";
import DialogContent from "@material-ui/core/DialogContent";
import DialogContentText from "@material-ui/core/DialogContentText";
import DialogTitle from "@material-ui/core/DialogTitle";
class RenderFile extends Component {
state = {
open: false
};
handleToggle = () => {
this.setState({
open: !this.state.open
});
};
handleClickOpen = () => {
this.setState({ open: true });
};
handleClose = file => {
// file = this.file;
this.setState({
open: false
});
window.open(`${file}`, "_blank");
};
handleCancel = () => {
this.setState({ open: false });
};
importAll = result => {
let images = {};
result.keys().map((item, index) => {
return (images[item.replace("./", "")] = result(item));
});
return images;
};
render() {
const webpackContext = require.context(
"../../uploads",
false,
/.(png|jpe?g|svg|pdf|doc|odt)$/
);
const images = this.importAll(webpackContext);
const { linkForRender } = this.props;
return (
<div>
<Button onClick={this.handleClickOpen}>Click to View File</Button>
<Dialog
open={this.state.open}
onClose={this.handleToggle}
aria-labelledby="form-dialog-title"
>
<DialogTitle id="form-dialog-title">Required Information</DialogTitle>
<DialogContent>
<DialogContentText>
Update these info to download the file
</DialogContentText>
<TextField
autoFocus
margin="dense"
id="name"
label="Email Address"
type="email"
fullWidth
/>
</DialogContent>
<DialogActions>
<Button onClick={this.handleCancel} color="primary">
Cancel
</Button>
<Button
onClick={this.handleClose.bind(this, images[`${linkForRender}`])}
color="primary"
>
View or Download File
</Button>
</DialogActions>
</Dialog>
</div>
);
}
}
add a comment |
Answering my own question (in case it helps anybody else) -
The mistake I was making is this -
When passing data from my FileUpload.js
.map
function to the handleClose
funtion passing the fileLink to render, I was not implementing any way to hook into that particluar file referred by the link.
Corrected it by A) From FileUpload.js when clicking on the Button to Download/View file, now I am rendering a completely new component ( RenderFile.js
) which will take care of opening the Material-UI modal and rendering the correct link for viewing the file.
This is my updated FileUpload.js file
class FileUpload extends Component {
state = {
documents: ,
clicked: false,
textBeforeDownload: "View/Download"
};
launchRenderFileComp = () => {
this.setState({
clicked: true,
textBeforeDownload: ""
});
};
deleteDocument = id => {
axios.delete("/api/document/" + id).then(() => {
this.setState({
documents: this.state.documents.filter(document => document._id !== id)
});
});
};
componentDidMount() {
axios.get("/api/document").then(res => {
this.setState({ documents: res.data });
});
}
importAll = result => {
let images = {};
result.keys().map((item, index) => {
return (images[item.replace("./", "")] = result(item));
});
return images;
};
render() {
const { documents } = this.state;
const webpackContext = require.context(
"../../uploads",
false,
/.(png|jpe?g|svg|pdf|doc|odt)$/
);
const images = this.importAll(webpackContext);
return (
<div className="bg-success">
<Col xs="8">
<Card>
<CardHeader className="p-2 mb-2 bg-primary text-white" />
<CardBody>
<CardText>
<table className="table table-stripe">
<thead>
<tr>
<th>Document Id</th>
<th>Description</th>
</tr>
</thead>
<tbody>
{documents.map(document => (
<tr>
<td>{document.document_id}</td>
<td>{document.description}</td>
<td>
<Button onClick={this.launchRenderFileComp}>
{this.state.clicked ? (
<RenderFile linkForRender={document.path} />
) : null}
{this.state.textBeforeDownload}
</Button>
</td>
<td>
<Link
to={`/api/document/edit/${document._id}`}
class="btn btn-success"
>
Edit Description
</Link>
</td>
<td>
<button
onClick={this.deleteDocument.bind(
this,
document._id
)}
className="btn btn-danger"
>
Delete
</button>
</td>
</tr>
))}
</tbody>
</table>
</CardText>
</CardBody>
</Card>
</Col>
And this is the new RenderFile.js compoenent that will take care of both opening the modal and rendering the file.
import React, { Component } from "react";
import Button from "@material-ui/core/Button";
import TextField from "@material-ui/core/TextField";
import Dialog from "@material-ui/core/Dialog";
import DialogActions from "@material-ui/core/DialogActions";
import DialogContent from "@material-ui/core/DialogContent";
import DialogContentText from "@material-ui/core/DialogContentText";
import DialogTitle from "@material-ui/core/DialogTitle";
class RenderFile extends Component {
state = {
open: false
};
handleToggle = () => {
this.setState({
open: !this.state.open
});
};
handleClickOpen = () => {
this.setState({ open: true });
};
handleClose = file => {
// file = this.file;
this.setState({
open: false
});
window.open(`${file}`, "_blank");
};
handleCancel = () => {
this.setState({ open: false });
};
importAll = result => {
let images = {};
result.keys().map((item, index) => {
return (images[item.replace("./", "")] = result(item));
});
return images;
};
render() {
const webpackContext = require.context(
"../../uploads",
false,
/.(png|jpe?g|svg|pdf|doc|odt)$/
);
const images = this.importAll(webpackContext);
const { linkForRender } = this.props;
return (
<div>
<Button onClick={this.handleClickOpen}>Click to View File</Button>
<Dialog
open={this.state.open}
onClose={this.handleToggle}
aria-labelledby="form-dialog-title"
>
<DialogTitle id="form-dialog-title">Required Information</DialogTitle>
<DialogContent>
<DialogContentText>
Update these info to download the file
</DialogContentText>
<TextField
autoFocus
margin="dense"
id="name"
label="Email Address"
type="email"
fullWidth
/>
</DialogContent>
<DialogActions>
<Button onClick={this.handleCancel} color="primary">
Cancel
</Button>
<Button
onClick={this.handleClose.bind(this, images[`${linkForRender}`])}
color="primary"
>
View or Download File
</Button>
</DialogActions>
</Dialog>
</div>
);
}
}
Answering my own question (in case it helps anybody else) -
The mistake I was making is this -
When passing data from my FileUpload.js
.map
function to the handleClose
funtion passing the fileLink to render, I was not implementing any way to hook into that particluar file referred by the link.
Corrected it by A) From FileUpload.js when clicking on the Button to Download/View file, now I am rendering a completely new component ( RenderFile.js
) which will take care of opening the Material-UI modal and rendering the correct link for viewing the file.
This is my updated FileUpload.js file
class FileUpload extends Component {
state = {
documents: ,
clicked: false,
textBeforeDownload: "View/Download"
};
launchRenderFileComp = () => {
this.setState({
clicked: true,
textBeforeDownload: ""
});
};
deleteDocument = id => {
axios.delete("/api/document/" + id).then(() => {
this.setState({
documents: this.state.documents.filter(document => document._id !== id)
});
});
};
componentDidMount() {
axios.get("/api/document").then(res => {
this.setState({ documents: res.data });
});
}
importAll = result => {
let images = {};
result.keys().map((item, index) => {
return (images[item.replace("./", "")] = result(item));
});
return images;
};
render() {
const { documents } = this.state;
const webpackContext = require.context(
"../../uploads",
false,
/.(png|jpe?g|svg|pdf|doc|odt)$/
);
const images = this.importAll(webpackContext);
return (
<div className="bg-success">
<Col xs="8">
<Card>
<CardHeader className="p-2 mb-2 bg-primary text-white" />
<CardBody>
<CardText>
<table className="table table-stripe">
<thead>
<tr>
<th>Document Id</th>
<th>Description</th>
</tr>
</thead>
<tbody>
{documents.map(document => (
<tr>
<td>{document.document_id}</td>
<td>{document.description}</td>
<td>
<Button onClick={this.launchRenderFileComp}>
{this.state.clicked ? (
<RenderFile linkForRender={document.path} />
) : null}
{this.state.textBeforeDownload}
</Button>
</td>
<td>
<Link
to={`/api/document/edit/${document._id}`}
class="btn btn-success"
>
Edit Description
</Link>
</td>
<td>
<button
onClick={this.deleteDocument.bind(
this,
document._id
)}
className="btn btn-danger"
>
Delete
</button>
</td>
</tr>
))}
</tbody>
</table>
</CardText>
</CardBody>
</Card>
</Col>
And this is the new RenderFile.js compoenent that will take care of both opening the modal and rendering the file.
import React, { Component } from "react";
import Button from "@material-ui/core/Button";
import TextField from "@material-ui/core/TextField";
import Dialog from "@material-ui/core/Dialog";
import DialogActions from "@material-ui/core/DialogActions";
import DialogContent from "@material-ui/core/DialogContent";
import DialogContentText from "@material-ui/core/DialogContentText";
import DialogTitle from "@material-ui/core/DialogTitle";
class RenderFile extends Component {
state = {
open: false
};
handleToggle = () => {
this.setState({
open: !this.state.open
});
};
handleClickOpen = () => {
this.setState({ open: true });
};
handleClose = file => {
// file = this.file;
this.setState({
open: false
});
window.open(`${file}`, "_blank");
};
handleCancel = () => {
this.setState({ open: false });
};
importAll = result => {
let images = {};
result.keys().map((item, index) => {
return (images[item.replace("./", "")] = result(item));
});
return images;
};
render() {
const webpackContext = require.context(
"../../uploads",
false,
/.(png|jpe?g|svg|pdf|doc|odt)$/
);
const images = this.importAll(webpackContext);
const { linkForRender } = this.props;
return (
<div>
<Button onClick={this.handleClickOpen}>Click to View File</Button>
<Dialog
open={this.state.open}
onClose={this.handleToggle}
aria-labelledby="form-dialog-title"
>
<DialogTitle id="form-dialog-title">Required Information</DialogTitle>
<DialogContent>
<DialogContentText>
Update these info to download the file
</DialogContentText>
<TextField
autoFocus
margin="dense"
id="name"
label="Email Address"
type="email"
fullWidth
/>
</DialogContent>
<DialogActions>
<Button onClick={this.handleCancel} color="primary">
Cancel
</Button>
<Button
onClick={this.handleClose.bind(this, images[`${linkForRender}`])}
color="primary"
>
View or Download File
</Button>
</DialogActions>
</Dialog>
</div>
);
}
}
edited Nov 14 '18 at 5:39
answered Nov 14 '18 at 5:27
Rohan_PaulRohan_Paul
7071015
7071015
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53284973%2freact-button-onclick-not-rendering-a-file-from-file-system-on-any-click-on-th%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
It's broken pal
require.context is not a function
– giwiro
Nov 13 '18 at 16:41
codesandbox will not run, I pushed the code there just to show my whole project - to see the full project you have to download to your machine and then do
sudo service mongod start
and then the following regular commands -npm install
-npm run dev
– Rohan_Paul
Nov 13 '18 at 16:45
How about using an arrow function instead of using bind here?
– VivekN
Nov 13 '18 at 21:35