angular2 http.post() to local json file - javascript

little help?
I am trying to write pure JSON to a file inside my project, my project tree looks like this:
src
->app
-->components
--->people.component.ts
--->(other irrelevant components)
-->services
--->people.service.ts
-->data
--->JSON.json
->(other irrelevant src files)
The code in my people.component.ts is just used to call and subscribe to a function inside my people.service.ts, passing the newPerson property which is data-binded from the DOM using angular2 magic; this is the function inside name.service.ts:
public addPerson(newPerson) {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
return this.http.post('app/data/PEOPLE.json', newPerson, { header: headers })
.map(res => res.json())
}
My objective is to write (if necessary replace) the newPerson property (or the entire file) inside PEOPLE.json. of course, the current addPerson() function returns an error.
I've also tried the put method, it errors slightly differently, but i haven't found solutions to either method.
I know categorically it's not an error with the format/type of data i'm trying to put in PEOPLE.json file.

Unfortunately, you can not PUT or POST directly to a file on your local filesystem using client side (browser) JavaScript.
Consider building a simple server to handle a POST request. If you are most comfortable with JavaScript, try Express with Node.js
// server.js
'use strict'
const bodyParser = require('body-parser');
const express = require('express');
const fs = require('fs');
const app = express()
app.use(bodyParser.json());
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'http://localhost:8000');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
res.header('Access-Control-Allow-Methods', 'POST');
next();
});
app.post('/', (req, res) => {
console.log('Received request');
fs.writeFile('json.json', JSON.stringify(req.body), (err) => {
if (err) throw err;
console.log('File written to JSON.json');
res.send('File written to JSON.json')
})
});
app.listen(3000, ()=>{
console.log('Listening on port 3000. Post a file to http://localhost:3000 to save to /JSON.json');
});

You cannot write to files from Browser. Period. Even if such action is possible it will be stored on User side, not your server. If your task is indeed to write something on user end, please refer to localStorage documentation (or couple other API implementations). But if you are going to user that file for some purpose outside of your browser, it will be non-trivial task.
If you want to save file on server, then you need to hande it on back end.

Related

How to upload an image to a node server endpoint using pure javascript?

I'm trying to create a small service that converts images from one type to another.
I'll get to the conversion part later, right now i cant even send it to the node server properly.
i have a simple script that's supposed to use filesystem to read an image and then POST it to a node server endpoint.
I couldn't find a way to do this anywhere online
i tried all kinds of different ways and formats, but on the endpoint the req.body is always an empty object or just an error
const fse = require('fs-extra');
var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
var xhr = new XMLHttpRequest();
fse.readFile('testimg.png', function (err, data) {
if (err) {
throw err
}
console.log(data)
xhr.open("POST", 'http://localhost:3000/convert', true); // true for asynchronous
xhr.setRequestHeader('Content-Type', 'application/upload');
xhr.send(data)
})
and this is the server endpoint:
var express = require('express');
var router = express.Router();
router.get('/', (req,res)=>{
res.send("hello")
})
router.post('/', async(req,res)=>{
console.log(req.body);
res.send("Hello i work")
})
module.exports = router;
What i want is to get the data on the server endpoint and to be able to process it and convert it for example: upload jpg and convert and send back as png or the opposite.
Help highly appreciated

Connecting Node.js script to a front-end project

As a javascript newbie, I want to create a front-end project with a very little backend solution using Node.js.
I have a user inteface with some variables and a button. These variables have to be passed to a simple .txt file(on my filesystem) and overwrite its content. For this, I'm using a nodejs script:
var fs = require('fs');
fs.writeFile('log.txt', 'This is my text', function (err) {
if (err) throw err;
console.log('Replaced!');
});
But I want this to work onClick, whereas this only works from the command-line.
So I have the two following problems:
I want to update the .txt file with the button click. So basically the above written code has to be executed, when I click the button. But I don't understand, how to connect the front-end with this nodejs file.
I want the content to be dynamical. I'm sure, once the first problem is solved, this will be straightforward, but right now I don't know this either.
I'm 100% sure I'm missing something(maybe a web-server, but even then, how?). I did my research but all I found was either an overkill or I didn't even understand it. Any help would be appreciated, a tutorial, an advice or just a keyword, that I can use for my research.
Have a look at express. It's a "Fast, unopinionated, minimalist web framework for node". With this you can build a small webserver:
var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send('Hello World');
});
app.listen(3000); // Webserver is running on port 3000
If you run it and got to your browser on http://localhost:3000, it would print Hello World.
Now what you would do is calling your logging function every time a specific URL is requested.
var fs = require('fs');
function log(text, callback) {
fs.writeFile('log.txt', text, callback);
}
app.get('/', function (req, res) {
log('This is my text', function (err) {
if (err) throw err;
res.send('Replaced!');
});
});
Now when you click the button you need to make an AJAX request to the server (maybe using jQuery).
Node.js doesnt have a built in front-library like some other scripting languages such as Python or VB. To create a node.js your intuition was correct in that you will need your app to expose itself as a web-server.
The popular library to do this is called express and it is very easy to get started.
I suggest that you follow the express quickstart tutorial to get into it.
From here you can wrap your code inside a route of the webserver (say /save) for example
var fs = require('fs');
var express = require('express');
var app = express();
app.get('/save', function (req, res) {
fs.writeFile('log.txt', 'This is my text', function (err) {
if (err) throw err;
console.log('Replaced!');
res.send('Replaced!')
});
})
app.listen(3000, () => console.log('Example app listening on port 3000!'))
With this example with the dependencies installed opening localhost:3000/save in your browser would cause your code to be run.

URL rewriting not working in Express 4.14.1

I've found in quite a few SO posts that in order to rewrite a URL in Express 4 I would do something like the following:
router.use('/one/:someId', (req, res, next) => {
req.url = `/two/${req.params.someId}`;
next();
});
router.get('/one/:someId', (req, res) => {
res.send("reached /one/:someId");
});
router.get('/two/:someId', (req, res) => {
res.send("reached /two/:someId");
});
But when I try this, not only does the URL does not change to my expected "/two/some integer" and stays being "/one/some integer" but it gets to the 404 - Not Found page I have set up in my app file.
This routes are in a router file and I have also tried setting the URL to:
req.url = `/routerPath/two/${req.params.someId}`;
but the result is exactly the same.
So what could I be missing?
Thank you.
You have to distinguish two kinds of redirects:
Internal redirects work on the server, without the client noticing. They are a convenience for your server programming and never necessary - you could always introduce a helper method that gets called by all endpoints.
HTTP redirects advise the client (e.g. a web browser) to go to a different URL. Since you expect the URL to change, that's the one you want.
Simply call res.redirect, making sure to encode special characters:
router.get('/one/:someId', (req, res) => {
res.redirect(`/two/${encodeURIComponent(req.params.someId)}`);
});
router.get('/two/:someId', (req, res) => {
res.render("reached /two/:someId");
});

Modify Request body and then proxying in Node.js

I am a relative newbie of Node.js. It been two days that I am trying to modify the body of a Request in Node.js and then forwarding it. For proxying I am using http-proxy module.
What I have to do is to intercept the password of a user inside a JSON object, encrypting it and set the new encrypted password inside the request body.
The problem is that every time I try to collect the request body I consume it (i.e. using body-parser). How can I accomplish this task? I know that the Request in node is seen has a stream.
For sake o completeness, I am using express to chain multiple operation before proxying.
EDIT
The fact that I have to proxy the request is not useless. It follows the code that I am trying to use.
function encipher(req, res, next){
var password = req.body.password;
var encryptionData = Crypto().saltHashPassword(password);
req.body.password = encryptionData.passwordHash;
req.body['salt'] = encryptionData.salt;
next();
}
server.post("/users", bodyParser.json(), encipher, function(req, res) {
apiProxy.web(req, res, {target: apiUserForwardingUrl});
});
The server (REST made by Spring MVC) give me the exception Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: null
The real problem is that there is an integration problem between modules body-parser and http-proxy, as stated in this thread.
One solution is to configure body-parser after http-proxy. If you can't change the order of the middleware (as in my case), you can restream the parsed body before proxying the request.
// restream parsed body before proxying
proxy.on('proxyReq', function(proxyReq, req, res, options) {
if (req.body) {
let bodyData = JSON.stringify(req.body);
// if content-type is application/x-www-form-urlencoded -> we need to change to application/json
proxyReq.setHeader('Content-Type','application/json');
proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
// stream the content
proxyReq.write(bodyData);
}
}
Why don't use express chaining for this ?
In your first function just do something like this :
req.body.password = encrypt(req.body.password); next();
You just have to use a middleware.
body-parser is also just a middleware that parses the request bodies and puts it under req.body
You can do something like this:
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
function encryptPassword(req, res, next) {
req.body.password = encrypt(req.body.password);
// You can do anything really here and modify the req
//call next after you are done to pass on to next function
next();
}
app.use(encryptPassword);
Generally people use middlewares for authentication, role-based access control etc.....
You can use middlewares in particular routes also:
app.post('/password', encryptPassword, function(req, res) {
// Here the req.body.password is the encrypted password....
// You can do other operations related to this endpoint, like store password in database
return res.status(201).send("Password updated!!");
});

Trouble extracting request data in Node.js (Express)

I'm trying to extract data from a request (in this case a POST) and am having trouble. I'm doing so using the body-parser module. Below is a portion of my code (note I am using ES6 syntax):
let bodyParser = require('body-parser')
var urlEncodedParser = bodyParser.urlEncoded({extended: true})
app.post('*', setFileMeta, setDirDetails, urlEncodedParser, (req, res, next) => {
async ()=> {
if (!req.stat) return res.send(405, 'File does not exist')
if (req.isDir) return res.send(405, 'Path is a directory') // This is an advanced case
await fs.promise.truncate(req.filePath, 0)
req.pipe(fs.createWriteStream(req.filePath)) // Filepath is a file
// This below line is where I need the body
sendToClients('update', req.url, 'file', req.body, Date.now())
res.end()
}().catch(next)
})
For the actual extraction of the data using body-parser, urlEncoded is the only way I was able to successfully do it (the data is just a string for now), and it's giving me in the format {content: ''} where content is the actual string I'm using. This isn't ideal but it works in this simple. However, this is breaking the createWriteStream(req.filePath) as seen above - the file is created, but there is no content.
There must be something obvious that I'm doing incorrectly, as I'm new to Node and Express. Since I wrote the majority of this with the help of an instructional video, my gut tells me it's the body extraction part since I'm doing that on my own.
body-parser exhausts (fully reads) the request stream in order to parse the incoming parameters, so there's no data left in the request stream to write to your file.
It seems to me that you're trying to implement file uploads. In that case, you probably want to use a module like multer instead of body-parser.

Categories

Resources