React- Button Onclick NOT rendering a file from file-system - On any click on the link Its alwasys rendering...












0















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.










share|improve this question

























  • 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
















0















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.










share|improve this question

























  • 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














0












0








0








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.










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 14 '18 at 4:23







Rohan_Paul

















asked Nov 13 '18 at 16:05









Rohan_PaulRohan_Paul

7071015




7071015













  • 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



















  • 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

















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












1 Answer
1






active

oldest

votes


















0














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>
);
}
}





share|improve this answer

























    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
    });


    }
    });














    draft saved

    draft discarded


















    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









    0














    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>
    );
    }
    }





    share|improve this answer






























      0














      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>
      );
      }
      }





      share|improve this answer




























        0












        0








        0







        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>
        );
        }
        }





        share|improve this answer















        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>
        );
        }
        }






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 14 '18 at 5:39

























        answered Nov 14 '18 at 5:27









        Rohan_PaulRohan_Paul

        7071015




        7071015






























            draft saved

            draft discarded




















































            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.




            draft saved


            draft discarded














            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





















































            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







            Popular posts from this blog

            Xamarin.iOS Cant Deploy on Iphone

            Glorious Revolution

            Dulmage-Mendelsohn matrix decomposition in Python