ReactJS + NodeJS server + Filepond uploading file - reactjs

I have a simple reactJS application. In this app, I have a web page where I am testing the Filepond component. I also have a nodeJs server, called by the Filepond component when the file is uploaded.
Here is the code when Filepond component is defined:
render() {
return(....
<FilePond allowMultiple={false} name='file' acceptedFileTypes='application/pdf' server='http://localhost:80/upload' uploadId=999 />
....
);
}
What I want?
1 - upload a single PDF file
2 - pass the uploadId to the server when uploading the file
What is happening?
=> the file is uploaded but the acceptedFileTypes="application/pdf" is not taken into account because I can select any file, no matter its type
=> I am not able to pass/get the uploadId value
Any help on how I can achieve these 2 points?
Except these 2 points, the component works well and I am able to upload the file correctly.
Thank you,
Best regards

Have you registered the plugin for validating file type?
For example:
import { FilePond, registerPlugin } from 'react-filepond';
import FilePondPluginFileValidateType from 'filepond-plugin-file-validate-type';
registerPlugin(FilePondPluginFileValidateType);
class App extends React.Component { ...
Once you have installed and imported, then FilePond should do the rest on its own if you have the appropriate prop on the component.
As for the ID. What are you trying to accomplish with that? I have an implementation going to a node server and it managed to do everything I needed it to without the ID implementation.

Related

Authentication to serve static files on Next.js?

So, I looked for a few authentication options for Next.js that wouldn't require any work on the server side of things. My goal was to block users from entering the website without a password.
I've set up a few tests with NextAuth (after a few other tries) and apparently I can block pages with sessions and cookies, but after a few hours of research I still can't find how I would go about blocking assets (e.g. /image.png from the /public folder) from non-authenticated requests.
Is that even possible without a custom server? Am I missing some core understanding here?
Thanks in advance.
I did stumble upon this problem too. It took my dumbass a while but i figured it out in the end.
As you said - for auth you can just use whatever. Such as NextAuth.
And for file serving: I setup new api endpoint and used NodeJS magic of getting the file and serving it in pipe. It's pretty similar to what you would do in Express. Don't forget to setup proper head info in your response.
Here is little snippet to demonstrate (typescript version):
import { NextApiRequest, NextApiResponse } from 'next'
import {stat} from "fs/promises"
import {createReadStream, existsSync} from "fs"
import path from "path"
import mime from "mime"
//basic nextjs api
export default async function getFile (req: NextApiRequest, res: NextApiResponse) {
// Dont forget to auth first!1!!!
// for this i created folder in root folder (at same level as normal nextjs "public" folder) and the "somefile.png" is in it
const someFilePath = path.resolve('./private/somefile.png');
// if file is not located in specified folder then stop and end with 404
if (! existsSync(someFilePath)) return res.status(404);
// Create read stream from path and now its ready to serve to client
const file = createReadStream(path.resolve('./private/somefile.png'))
// set cache so its proper cached. not necessary
// 'private' part means that it should be cached by an invidual(= is intended for single user) and not by single cache. More about in https://stackoverflow.com/questions/12908766/what-is-cache-control-private#answer-49637255
res.setHeader('Cache-Control', `private, max-age=5000`);
// set size header so browser knows how large the file really is
// im using native fs/promise#stat here since theres nothing special about it. no need to be using external pckages
const stats = await stat(someFilePath);
res.setHeader('Content-Length', stats.size);
// set mime type. in case a browser cant really determine what file its gettin
// you can get mime type by lot if varieties of methods but this working so yay
const mimetype = mime.getType(someFilePath);
res.setHeader('Content-type', mimetype);
// Pipe it to the client - with "res" that has been given
file.pipe(res);
}
Cheers

Cant open local html file with WebView on React Native canOpenURL: failed for URL

2020-01-29 20:32:22.470194+0300 Myapp[8905:2391245]
-canOpenURL: failed for URL: "file:///private/var/containers/Bundle/Application/146EA027-7A**/Myapp.app/assets/src/assets/policy.html" - error: "This app is not allowed to query for scheme file"
I am getting this error on xCode console output on real device. On simulator, everything works fine.
Here is my simple full code:
import React, { Component } from 'react';
import { WebView } from 'react-native-webview';
const PolicyHTML = require('../assets/policy.html');
export default class PolicyScreen extends React.Component {
render() {
return (
<WebView
source={PolicyHTML}
style={{flex: 1}}
/>
);
}
}
Couldn't find much solution about that online, what am i missing ?
The solution for me was just add originWhitelist={['*']} in the <WebView> component and then iOS would load HTML correctly.
I was having the same issue, i am using webview and wanted to load my local html file in that webview, which works perfectly fine in Android but was not in IOS device. After a lot of research i ended up with the following solution.
I have placed my html file in the following path:
MyReactNativeProjectFolder>app>views>monthly>trip.html
Where monthly is my custom folder that i created myself and has a local html file called trip.html.
And in the view, lets say MyView.js, where i want to call my html file i used the following syntax:
<WebView originWhitelist={['*']} source={require('./monthly/trip.html')} ref={( webView1 ) => this.webView1 = webView1} />
MyView.js is in the follwing path:
MyReactNativeProjectFolder>app>views>MyView.js
If you are not getting any error on simulator then this shall fix your problem, otherwise try changing the html file path as I have mentioned above, that is in the views folder, and try again.
I hope this may resolve the error Unable to open URL file:///private/var/containers/Bundle/Application/146EA027-7A/Myapp.app/assets/src/assets/policy.html
I don't know is this can be considered as proper solution but here how i solved it;
I am not sure but as my thinking Xcode is not allowing some codes on html files, so I thought about that found some websites on google which converts to html files to 'clean html file' and removes the unnecessary codes. After cleaning I replaced the new clean file with old one and it worked.
Hope it helps (Especially in Privacy Policy Files).

load pdf from redux store

I am trying to download a server side generated pdf file in client, which i get with axios and save it in redux and using FileSaver to download it.
const getTicketPdf = ({ userID, ticketID }) =>
requestApi(`/users/${userID}/tickets/${ticketID}/pdf`, {
method: 'get',
});
requestApi gets me all neccessary headers so that i can download the file.
the data is then stored in redux like this:
data: "%PDF-1.4\n3 0 obj\n<</Type /Page\n/Parent 1 0 R\n/MediaBox [0 0 595.00 842.00]\n/Resources 2 0 R\n/Contents 4 0 R>>\nendobj\n4 0 obj\n<</Filter /FlateDecode /Length 64>>\nstream\nx�3R��2�35W(�*T0P�R0T(\u0007�Y#�\u000e��#Q…"
i call it in render with:
<div>
<button onClick={ () => this.getPdf(ticket) }>PDF</button>
</div>
getPdf = ticket => {
const blob = new Blob([ticket]);
FileSaver.saveAs(blob, 'Ticket.pdf');
}
I am always getting the following error:
TypeError: Cannot read property 'saveAs' of undefined
i tried also to set
responseType: 'blob'
but this doesn't help either.
Next thing I testet was with react-pdf library, where I managed to display pdf in Component, but i cant print it. User should only habe to save it and then print it locally (or at least show it in separate tab as PDF, which i tried with window.open() as base64 encoded string).
How can I download a server side generated PDF otherwise? Are there any better ways?
Unfortunately I have to set HTTP Headers in order to get that file.
Thanks in advance.
The error stems from the fact that there is no FileSaver object (or rather, it's non-standard).
It seems to be polyfilled by this third-party library: https://github.com/eligrey/FileSaver.js
The error you are seeing is caused by a reference to an undefined variable FileSaver - I guess that you are using FileSaver.js, and need to fix the import. You should also bear in mind that FileSaver is deprecated in favour of the download attribute. See this answer for details on how to use it.
Either way, in the interests of keeping your store light, you should save a reference to the PDF in your Redux store, rather than the string itself.

Angular file upload custom http post files

I am using nervgh/angular-file-upload to upload files. As I know, this angular-file-upload has their own upload functions.
Currently I need only the files inside the uploader, and then I will use my custom http post
$scope.UploadUserFiles = function () {
$scope.UserFileRequest = {"File": uploader, "User": myUser}
$http.post(host + "/api/user", $scope.UserFileRequest).then(function (response) { });
}
Currently I am having the trouble of getting those files from the uploader since I have no idea about the properties and structure. But for User is my own class at the web api, so I have no problem to get any info that I want.
The main problem is I have no idea how to catch/initialize the uploader it into a variable after post to my web api.
[HttpPost]
[Route("api/user")]
public UserFileResponse GetUserFile(UserFileRequest userFileRequest)
{
//What should I do to get the Files from the request and save into the server?
}
My UserFileRequest contain the info of myUser, but I do not know what to do with the uploader since I do not have a class to hold it.
From what I understand in your question, you are having trouble getting the files in the queue into your own file upload function.
The functions within the FileUploader class have callbacks that you can use, but another way to easily expose the file queue would be to create your own callback once the 'upload' button is clicked.
someFxn(item) {
console.log(item);
_someUploadFxn(item)
}
<md-button class="md-blue" ng-click="$ctrl.someFxn(item)" ng-disabled="item.isReady || item.isUploading || item.isSuccess">
Upload
</md-button>
This will allow you to view the file that has been queued up and from there you can pass it or whatever properties you need off that file object into your own uploader function.
The same goes for if you are wanting to upload a bunch of files at once.

XML sitemap for react app

I have a react app for which I want to add a sitemap.xml. I have added this route to link to the file (XML is my my sitemap.xml):
import XML from './sitemap.xml';
<Route component={XML} path={'/sitemap.xml'} />
I keep getting this error, which I understand it means that I need to add an xml loader to my webpack:
You may need an appropriate loader to handle this file type.
Not sure how to pick an xml loader as I could mostly find parsers (xml to json) and I am not sure if it's ok to have the sitemap in json. Also, is there any other native way of displaying the xml file without adding any loader?
If you are using create-react-app, just put your XML file in public folder (a folder beside node_modules and src folders), then access it through {base_url}/{XML_file_name.xml} (e.g. localhost:3000/sitemap.xml)
In , keyword component should be a React Component.
Check the documentation:Route - React Router
If you want to pass XML as a variable, you should change XML format to string and with another prop but component={}.To transform XML to String, ry escape(XML) before passing to Route! Check escape(str)
with import keyword, youcan try like this:
// file: get-xml.js
let transformXMLToString = () => {
// read the target XML fiel and transform it to String
// return the string
return XMLasString;
};
export transformXMLToString;
// then you could import the XML like this in another file:
import transformXMLToString from 'get-xml.js';
// then pass it to <Route> like:
<Route component={transformXMLToString()}/>
A simple solution would be to add
<a href="XML_PATH" style={{display:"none"}}>xml</a>
Then check your google chrome development console, search for the anchor(a) tag.
And follow the path

Resources