download sample file in public folder (react) - reactjs

I want to put a sample xlsx file in my public folder (react project) and others can download this file.
<Button><link rel="chargeSample" href="%PUBLIC_URL%/chargeSample.xlsx"></link></Button>
How can I do this?

The tag defines a link between a document and an external resource.
To let download funcionality on your website you should change link tag
import chargeSample from './public/chargeSample.xlsx';
<Button>Download</Button>

First of all, we have to think about where you store the file, thinking about what react is going to do in build time. In develop, you can't trust 100% that the paths you use are going to be the same after building the app.
Here in the create react app doc there is some info about when to use the public folder and how to use it.
To download a file stored in the public folder, you have to reference it with the PUBLIC_URL. There are two ways of doing this:
Reference a file from inside the public folder
You will have to use de %PUBLIC_URL% as you mentioned.
For example, if you want to use a fav icon in the main HTML file, you have to add the icon in the public folder and then in the index.html you will reference this file with the %PUBLIC_URL% prefix.
// public/index.html
// ...other stuff
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
// ...
In build time, React will replace this hash with the path to that folder
Reference a file in the src folder
To reference a file from inside the src folder, you have to access the public folder URL. React saves this path in an environment variable. To be able to use that file you have to use the process.env.PUBLIC_URL path.
To download a file from the public folder, you can access it like this:
<a
href={process.env.PUBLIC_URL + "/my-file.txt"}
download={"file-name-to-use.txt"}
>
Download file
</a>
When clicking the anchor tag it will try to download the file stored in /public with the name my-file.txt and it will use as a placeholder name for that file the one specified in the download property.

If you are using creat react app, you can pass public path into your components at build time by using
process.env.PUBLIC_URL

I believe that Lucas gave the best answer. Just to add since I was looking for a way to programmatically create a link element (let's say when you received a new excel file from an API call in runtime/deployment) then you can do something as follows:
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', `${Date.now()}.xlsx`); //set the attribute of the <a> link tag to be downloadable when clicked and name the sheet based on the date and time right now.
document.body.appendChild(link);
link.click(); //programmatically click the link so the user doesn't have to
document.body.removeChild(link);
URL.revokeObjectURL(url); //important for optimization and preventing memory leak even though link element has already been removed.
Credits to top answers here:
How to download files using axios
How to download excel in response from api react.js

Related

Downloading a file using React and Typescript

I am trying to build a single page app using React. I came up with this hacky way to download a local file (residing in the public directory). I have two questions:
Can I write this more cleanly?
Is there any better or more elegant way to download a local file?
const handleDownload = () => {
const tempComponent = document.createElement('a')
tempComponent.href = 'Dark.ask'
tempComponent.download = 'Dark.ask'
tempComponent.click()
tempComponent.parentElement?.removeChild(tempComponent)
}
1. No, it's always the same process: create link element, put encoded (base64, urlencoded) data to the link, programmatically click the link and then remove element
2. I think, better you should not place all data to href attribute of a element - it's all will be loaded to user ram.
Use stream saver: https://github.com/jimmywarting/StreamSaver.js
It will allow you to download any size of file from custom source (like API endpoint)
Or you can just put a link to the static file in [href], and when the user clicks the link, the browser will automatically start download, more: https://www.w3schools.com/tags/att_a_download.asp.
maybe duplicate of How to download large file with JavaScript

Using Spfx React-Application-Injectcss extension (link in des) to hide left side navigation on one particular site

I've built and applied this extension react-application-injectcss(https://github.com/pnp/sp-dev-fx-extensions/tree/master/samples/react-application-injectcss) but it applies on all sites in my tenancy. Can I hardcode site name of a particular site where I need to apply custom css/js
Where do I change in code (.ts file)?
You could use this extension to inject the js file to the page and judge the url of the current page in the js file, and then inject the CSS file.
if ((window.location.href.toLowerCase().indexOf('testfolder') > 0))
{
var head = document.getElementsByTagName('head')[0];
var link = document.createElement('link');
link.href = 'https://contoso.sharepoint.com/sites/dev/Doc/testFolder/test.css';
link.rel = 'stylesheet';
link.type = 'text/css';
head.appendChild(link);
}
extension inject js file
I would say that ideologically, injecting CSS to customize things you don't own is a bit hacky and potentially harmful way. To customize site appearance, you can use the site template. For example, to "get rid of the sidebar" you could create "communication" site (that does not have the sidebar) instead of "team" site (that does). As simple as that.

How do I access an environment variable from within the public folder?

In my create-react-app app I have a javascript file in my public folder. Within it, I need to access an environment variable named REACT_APP_ACTUAL_ENV but I'm not sure how I can. Trying the usual process.env.REACT_APP_ACTUAL_ENV doesn't work because process is undefined in the public folder. Looking at https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables, I can do %REACT_APP_ACTUAL_ENV% within an HTML file in the public folder and it works just fine. But the problem is I need to do this within a javascript file somehow, though I'm not sure if it's possible.
In my case, I have to reference REACT_APP_FACEBOOK_APP_ID environment variable to initialize Facebook SDK inside public/index.html file.
I simply assign the variable to HTML element's property then access it using JavaScript like so:
...
<meta property="fb:app_id" content="%REACT_APP_FACEBOOK_APP_ID%" />
<script>
const facebookAppId = document.querySelector('[property="fb:app_id"]').content;
// use `facebookAppId` here
</script>

Call a Angular js page in Play framework

I am finding trouble to display my AngularJs page from Play framework 2.2
The Angular js page is located in the same project directory which is
C:\webProj\test\app\www\index.html
Note this index.html is not the index.scala.html that we have in play views directory
I need to render this page from my Play project.
I have tried this
GET /masterid controller.Assets.at("/app/www/",index.html)
but it gives a compilation error.
Explanation of the error
There are some syntax errors in this route configuration:
GET /masterid controller.Assets.at("/app/www/",index.html)
It should be controllers instead of controller, the path is wrong, and the parameters are not specified correctly. It could be written as:
GET /masterid controllers.Assets.at(path="/app/www", file="index.html")
Note that as written, this route will map only to the index.html file, not to any other resources under /masterid.
Solution with a separate directory
To behave exactly as asked, with a separate directory and a custom URL, you would need to specity a second asset route in addition to the default one. This would also require changing all usages of #routes.Assets.at to specify two parameters (folder and file), and adding a configuration to build.sbt:
playAssetsDirectories <+= baseDirectory / "app/www"
Solution using the public directory and a custom URL
The path of least resistance is to create the custom index.html file in the project's public directory. To use a custom URL as asked in the question, you could change the default asset path to "masterid" by changing this line in the routes file:
GET /assets/*file controllers.Assets.at(path="/public", file)
to this:
GET /masterid/*file controllers.Assets.at(path="/public", file)
In this case the custom index.html file could be accessed as:
http://localhost:9000/masterid/index.html
Relative URLs to other resources under the /public folder would work as well.
Solution using the public directory and the default URL
If you don't require the /masterid URL under the root, you can save your index.html file under public/app and refer to it as:
#routes.Assets.at("app/index.html")
This will resolve to:
http://localhost:9000/assets/app/index.html
Documentation
For more extensive instructions see Working with public assets.
Make it faster, just place your file in i.e.: /public/angular-app/index.html, so you can use it via:
#routes.Assets.at("angular-app/index.html")
Next (assuming that you have standard routes) you can just use static paths to your public assets, i.e. if image is placed in folder public/img/logo.png you can access it with:
<img src="/assets/img/logo.png" alt=""/>
So just by replacing public/ to /assets/ (slash at beginning to make sure you don't need to use base tag in head of document).

Relative paths for javascript on CakePHP2

I was wondering if there's any way to do something similar to what HtmlHelper does in Cake views: instead of having to write the URL manually, calling some kind of helper to make it for you.
I have taken a look at this post but it is from 2010 and maybe there's something new now...
Currently I have codes like this at my javascript files:
window.location.href = 'http://' + document.domain +'/cakephp/posts/view/'+$(this).attr('data-id');
But if i change the cakephp folder name, or I use another configuration on the server or something similar, the URL changes and I should change manually all the codes with this type of URL.
I wonder if there's something similar to:
echo $this->Html->link('controller' => 'users' , 'action' => 'login');
Are you referring to inline or external JavaScript? Inline is rather easy using the url method, which accepts the same arguments as link (an array or string containing the URL).
Using it in external files is a bit trickier. I define a JS variable containing the site path before loading the JS files.
<script type="text/javascript">
//<![CDATA[
var SITE_URL = "http://www.example.com/cakeapp/";
//]]>
</script>
In my external JavaScript files I can then reference SITE_URL when I need it. When you change domains or rename the cakeapp directory you only have to alter the SITE_URL variable.

Resources