Moving a file from a React.JS frontend to a C++ backend - javascript

So I have a function written in C++, that works on a file. I can convert it to a script and the script to take a parameter of the file location for example and work on it, that is not a problem.
My frontend is done with React, it is still not connected to the backend. I have a button that is "Upload File" the user clicks, and I need to have this file on my backend to run the C++ code on it.
Theoretically, the way I thought of (Not sure if it works):
User chooses the file to upload
From the frontend, we upload it to a cloud storage such as Google Drive for example
Then, from the Frontend I send an HTTP request using a REST API, with parameter as the file direct download link.
Then the REST API runs a Python function that executes the following shell commands:
wget (link that we got from the HTTP request through REST API
And after that the python script runs the C++ function on the file, and returns the output through the HTTP request.
Does that make sense?
Is there an easier or better way?
Thanks

Problem
Have the user load a file -> have the C++ function run on that file -> return output to the user.
Possible Solution with REST-API
As you stated in your question you could upload to google drive and then wget the file, however its a bit too complex for nothing. What you could do instead is skip the uploading to the Google drive and directly send the file through formdata.
Here is a working example in React taken from here:
import React from 'react'
import axios, { post } from 'axios';
class SimpleReactFileUpload extends React.Component {
constructor(props) {
super(props);
this.state ={
file:null
}
this.onFormSubmit = this.onFormSubmit.bind(this)
this.onChange = this.onChange.bind(this)
this.fileUpload = this.fileUpload.bind(this)
}
onFormSubmit(e){
e.preventDefault() // Stop form submit
this.fileUpload(this.state.file).then((response)=>{
console.log(response.data);
})
}
onChange(e) {
this.setState({file:e.target.files[0]})
}
fileUpload(file){
const url = 'http://example.com/file-upload';
const formData = new FormData();
formData.append('file',file)
const config = {
headers: {
'content-type': 'multipart/form-data'
}
}
return post(url, formData,config)
}
render() {
return (
<form onSubmit={this.onFormSubmit}>
<h1>File Upload</h1>
<input type="file" onChange={this.onChange} />
<button type="submit">Upload</button>
</form>
)
}
}
Possible Other Solution with AWS Lambda
For your specific use case I would not recommend having a full-blown REST-API, you could simply use a event-driven lambda function like AWS Lambda. This way you only need to upload to Google Drive or S3 bucket and then the Lambda will run and generate an output which can be returned to the user.

Related

js function calling an api doesn't respond with expected values

I am trying to collect all the market pairs from a crypto exchange using its API, but I'm not sure how to select the proper line in the JSON object as it does not seem to work.
the api : https://ftx.com/api/markets
my code :
requests.js
import axios from 'axios';
import parsers from './parsers';
async function ftxMarkets() {
const ftxResponse = await axios.get('https://ftx.com/api/markets');
return parsers.ftxMarkets(ftxResponse.data);
}
parsers.js
function ftxMarkets(data) {
const [ftxMarketPairs] = data;
let ftxPairs = data.map(d => d.name );
console.log(ftxPairs);
};
I'm not sure about d.name in the parsers.js file, but I tried with another exchange with the same code, changing just that part and it worked, so I guess that's where the problem comes from, although can't be sure and I don't know by what to replace it.
Thanks
I ran the api call and after looking at the response I see a result key with the list of all crypto data. So I am guessing it'll work if you call the parser with the result object like this
return parsers.ftxMarkets(ftxResponse.result);
// try parsers.ftxMarkets(ftxResponse.data.result) if the above one doesnt work
and then in the parser it should work normally
function ftxMarkets(data) {
let ftxPairs = data.map(d => d.name );
console.log(ftxPairs);
};
Update:
Since fxtResponse.data.result works. Your issue should be a CORS issue and to fix that there are two options.
CORS plugin in web browser(not recommended in production)
Proxy it through a server. By requesting the resource through a proxy - The simplest way, what you can do is, write a small node server (or if you already have a back-end associate it with your front-end you can use it) which does the request for the 3rd party API and sends back the response. And in that server response now you can allow cross-origin header.
For 2 If you already have a nodeJs server. You can use CORs Npm package and call the third party api from the server and serve the request to the front end with CORS enabled.

expo- react native : there is way to see the content of the expo FileSystem and also delete content from there?

there is way to see the content of the FileSystem and also delete content from there?
i have data inside the expo FileSystem and i need :
look inside FileSystem because i dont know how to find this file because i work with the expo client sdk with the qr code scan and i dont understand how can i find this file there .
i want to know how to delete contents from the file system .
how can i see the sqlite database as a real table ?
this is my examle :
saveDbData = async () => {
const { data, isLoaded } = this.state;
for (let i = 0; i < data.length; i++) {
const mediaData = data[i];
const dbResult = await insertPlace(
mediaData.artist,
mediaData.image,
mediaData.title,
mediaData.url
);
console.log("SQL", `${FileSystem.documentDirectory}/SQLite/places.db`);
}
const fetchawesome = await fetchPlaces();
console.log(fetchawesome)
};
Since there are three questions from your part, I'll try to answer them one by one and provide a possible solution.
look inside FileSystem because i dont know how to find this file
because i work with the expo client sdk with the qr code scan and i
dont understand how can i find this file there .
You can access the file system using the FileSystem package from expo. Here's how you can do it. Import the package first.
import * as FileSystem from "expo-file-system";
Then you can find the URI of the file like this.
const { uri } = await FileSystem.getInfoAsync(
`${FileSystem.documentDirectory}SQLite/${"yourDB.db"}`
);
I want to know how to delete contents from the file system.
You can delete a file if you have access to its location or URI. This is how you can delete it. It returns a promise.
FileSystem.deleteAsync(fileUri)
how can I see the SQLite database as a real table?
This is a tricky part because since you're using your android phone to run the application via expo, you won't have direct access to your db. One thing you can do is to move the db to someplace else where you have access to and using the Sharing API from expo to save or send the db to yourself via email or any other way.
import * as Sharing from "expo-sharing";
let documenturi = `${FileSystem.documentDirectory}/yourDB.db`;
await FileSystem.copyAsync({
from: uri,
to: documenturi,
});
Sharing.shareAsync(documenturi);
You can make this as a function which fire's on a Button press on you can even put this in useEffect or lifecycle methods to fire up when the screen loads.

How to use translate pipe of ng2-translate to pass key for tanslation with out using .json file path

With .json the following is working fine:
export function createTranslateLoader(http: Http) {
return new TranslateHttpLoader(http, 'src/app/test/', '.json');
}
But I need how can I get translated data from service like CMS. How to pass two parameters to a translate pipe (key and sitemapid)? And how to write service to hit the server.
TranslateHttpLoader(http,'http://test.test.com/ts/content/Translations/{lang}/{sitemapid}');
Ngx-translate works great with json. You can use its pipe and services. In our project, on server side application startup, we fetch every messages in CMS and put them in a json file. Then, load that json file with ngx-translate.
However, If you need to access a link and get only single message, you should just use http.
http.get(`http://test.test.com/ts/content/Translations/${lang}/${sitemapid}`)
.map(res => res.json()).subscribe(res => this.message = res);

Error when using React.js and the Twilio API

I'm investigating creating a small Twilio app for a project using React.js. I'm fairly good at React and JavaScript (but not an expert), but I'm having a bit of trouble.
Initially, I am trying to load all the messages on the account to the webpage. Here is the code I have:
import React from 'react'
import {connect} from 'react-redux'
var accountSid = '####';
var authToken = "####";
var client = require('twilio')(accountSid, authToken);
var msgList = []
const messages = () => {
client.messages.list(function(err, data) {
data.messages.forEach(function(message) {
msgList.push(message)
});
})
return msgList
}
class LandingPage extends React.Component {
render() {
return (
<h1>Hello!</h1>
)
}
}
export default connect(select)(LandingPage)
(of course, there are more files, but this is my current working file where I am having the issues).
First of all, when I load this up in my browser, I get an error in the console:
Uncaught TypeError: querystring.unescape is not a function
This apparently relates to the client.messages.list(function(err, data) { line.
Also, how would I go about rendering each message.body? I guess I would have to use a for loop but I'm not sure where that would go here.
The library you are trying to use was written for Node.js, and I assume you're trying to use it in the browser or in React Native? A couple bits:
You shouldn't use the Twilio API from a client side application with your account SID and auth token. These credentials are the "keys to the kingdom" for your Twilio account, and can be compromised if you put them in any client-side app.
The module you are trying to use was written for Node.js, and may not work out of the box in the browser. I haven't tested it, but it might work with Browserify if you were to package your front-end code that way.
For the use case you're trying to implement, I would fetch the messages on your server, and send them to the client via Ajax rather than hitting the API directly from the client.

How to Handle Post Request in Isomorphic React + React Router Application

I want to build Isomorphic react + react-router application and after a few days googling, now I can achieve isomorphic application that only handles GET request.
Here's what I've done so far:
Server use react-router to handle all request
react-router will call fetchData functions that resides in each React View that matches the route.
Set the data fetched before into props of the React View and render it into string
Inject the string and data fetched before as global variable window.__STATE__ into HTML and deliver the HTML to the client
We have successfully render React App from the server
When the client finished loading our React App javascript, it will try to render. But we pass the state from window.__STATE__ as the props of our React App, and React will not re-render because the state is the same
The problem is it will not work with POST/PUT/DELETE/WHATEVER request. When handling GET request, react-router have information about params and query. For example if we have a route: /user/:uid and client request this url: /user/1?foo=bar, then params would be: {uid: 1} and query would be {foo: 'bar'}
react-router then can pass it down to fetchData function so it will know to fetch user with uid of 1 and do whatever with foo query.
While in POST request, react-router doesn't know about the POST parameters. On Server, of course we could pass the POST parameters to fetchData function, but what about the Client? It doesn't know what the POST parameters are.
Is there a way that the server could tell the Client about the POST parameters? Below is an example of my Login View. I want when user submit the form, the server will render error message on error, or redirect it to dashboard on success.
fetchData.js
import whenKeys from 'when/keys';
export default (authToken, routerState) => {
var promises = routerState.routes.filter((match) => {
return match.handler.fetchData;
}).reduce((promises, match) => {
promises[match.name] = match.handler.fetchData(authToken, routerState.params, routerState.query);
return promises;
}, {});
return whenKeys.all(promises);
}
server.js
...
app.use((req, res) => {
const router = Router.create({
routes,
location: req.originalUrl,
onError: next,
onAbort: (abortReason) => {
next(abortReason);
}
});
router.run((Handler, state) => {
fetchData(authToken, state).then((data) => {
// render matched react View and generate the HTML
// ...
})
});
});
...
login.jsx
import React from 'react';
import DocumentTitle from 'react-document-title';
import api from './api';
export default class Login extends React.Component {
constructor(props) {
super(props);
// how to fill this state with POST parameters on error?
// how to redirect on success?
// and remember that this file will be called both from server and client
this.state = {
error: '',
username: '',
password: ''
};
}
// I saw some people use this function, but it'll only work if
// the form's method is GET
static willTransitionTo(transition, params, query) {
// if only we could read POST parameters here
// we could do something like this
transition.wait(
api.post('/doLogin', postParams).then((data) => {
transition.redirect(`/dashboard`);
});
);
}
render() {
return (
<DocumentTitle title="Login">
<div className="alert alert-danger">{this.state.error}</div>
<form method="post">
<input type="text" name="username" value={this.state.username} onChange={this._onFieldChange('username')} placeholder="Username" /><br />
<input type="password" name="password" value={this.state.password} onChange={this._onFieldChange('password')} placeholder="Password" /><br />
<button type="submit">Login</button>
</form>
</DocumentTitle>
);
}
_onFieldChange(name) {
var self = this;
return (e) => {
e.preventDefault();
var nextState = {};
nextState[name] = e.target.value;
self.setState(nextState);
}
}
}
Getting "POST" data on the client
On the client side, you get POST data by extracting values from your form inputs in a way which corresponds to what you would have received on the server had the form been submitted normally.
Using POST data
So now you have your POST data, but you still have the problem that there's no way to feed the POST data into your transition hooks in React Router 0.13.x and earlier. I created a pull request for this feature which has now been closed because it was included as part of the rewrite for the upcoming v1.0 release.
The gist of it is that locations now have a state object for squireling away any extra data you need about the current request/transition (the two are analagous) being handled:
On the server, you're dealing with one request at a time, so you create a static Location with data from req.body
On the client you pass the state object (containing extracted form data) to transitionTo().
Now your transition hook is capable of receiving the same form data in both environments. If things go well, great! If things don't go well, you need a way to pass errors and re-render the form again. New state object to the rescue again! Use transition.redirect() and pass both input data and errors and you now have everything you need to render on both sides.
I'm not going into more specific detail right now because v1.0 is still in beta and v0.13.x doesn't have the necessary API to do this anyway, but I have a repository which uses the pull request above to implement this workflow with 0.13.x which you could look at in the meantime:
isomorphic-lab - the README gives an overview of how things fit together.
Here are some rough flow diagrams of the process, too:
Server POST with errors and redisplay
Client POST with errors and redisplay
I've also created a few reusable modules related to this scenario:
get-form-data gets data from a form's inputs in the format it would have been POSTed in.
react-auto-form provides <AutoForm>, which you can use instead of <form> to receive all the data from a form's inputs as an argument to its onSubmit handler
react-router-form, which is to <form> what React Router's <Link> is to <a> - it handles triggering a transition to the given action, passing method and body (form data) state - this will be updated for v1.0 soon.

Categories