Create rest api to retrieve data from odoo erp - javascript

I am creating a rest api service to get, put, delete data from odoo erp .
Here is my code :
const Promise = require('bluebird');
Promise.promisifyAll(require('node-odoo').prototype);
const Odoo = require('odoo-xmlrpc');
const odoo = new Odoo({
url: 'zzzz',
port: 'zz',
db: 'zzzz',
username: 'zzzz',
password: 'zzz*'
});
var express = require('express'),
app = express(),
port = process.env.PORT || 3000;
this.router = express.Router();
app.listen(port);
console.log('todo list RESTful API server started on: ' + port);
this.router.get('/api/event/', (req, res) => {
return getEvent(req, res);
});
app.get('/getEvent', (request, response) => {
odoo.connect((err) => {
if(err) return console.log('Findeventlist error ' + err);
console.log('Findeventlist connected ' );
var inParams = [];
inParams.push([]);
inParams.push(['name' ])
inParams.push(0)
inParams.push(5)
var params = [];
params.push(inParams);
odoo.execute_kw('calendar.event', 'search_read', params, function (err, value) {
if (err) { return console.log(err) }
if(value){
console.log( 'Value is ' + response.status(200).json(value));
return response.status(200).json(value)
}
});
});
console.log(' odoo connected');
})
I got this error : Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
Can you help me please where i'm wrong?

response.status(200).json(value) responds to the client and ends the transaction (just like response.end() or response.sendFile() etc).
It must be called only once, but you execute it twice (once inside the console.log() then once "for real" the next line). That's why the headers are "already sent".
Remove the useless response.json() from the console.log and log only the value you want to see.

Related

Using passport for socket.io

Hi im trying to use passport for authencication, But im not sure what to do on the client side. I think the server side is fine, but it gives me this error:failed: WebSocket is closed before the connection is established. So it seems like it cant get the connection. what do i need to send from the client side, and do i need to change something on server side??
please heeeelp thanks:)
server.js
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require("socket.io")(server, {
cors: {
origin: "*",
methods: ["GET", "POST"]
}
});
var port = process.env.PORT || 4000;
const passportSocketIo = require('passport.socketio')
const cookieParser = require('cookie-parser')
const session = require("express-session")
const passport = require('passport')
io.use(passportSocketIo.authorize({
cookieParser: cookieParser,
key: 'express.sid',
secret: 'session_secret',
store: session,
success: onAuthorizeSuccess,
fail: onAuthorizeFail,
}));
function onAuthorizeSuccess(data, accept){
console.log('successful connection to socket.io');
// The accept-callback still allows us to decide whether to
// accept the connection or not.
accept(null, true);
// OR
// If you use socket.io#1.X the callback looks different
accept();
}
function onAuthorizeFail(data, message, error, accept){
if(error)
throw new Error(message);
console.log('failed connection to socket.io:', message);
// We use this callback to log all of our failed connections.
accept(null, false);
// OR
// If you use socket.io#1.X the callback looks different
// If you don't want to accept the connection
if(error)
accept(new Error(message));
// this error will be sent to the user as a special error-package
// see: http://socket.io/docs/client-api/#socket > error-object
}
io.on('connection', function (socket) {
console.log("connection")
var addedUser = false;
// when the client emits 'new message', this listens and executes
socket.on('new message', function (data) {
var data = validator.escape(data);
// we tell the client to execute 'new message'
socket.broadcast.emit('new message', {
username: socket.username,
message: data
});
db.serialize(function() {
// console.log('inserting message to database');
var insertMessageStr = "INSERT INTO messages (username, content, posted) VALUES ('" + socket.username + "','" + data.toString() + "'," + Date.now() + ");"
// console.log(insertMessageStr)
db.run(insertMessageStr);
});
});
client.js
const socket = io({
key: 'express.sid',
secret: 'session_secret',
});

Post request not working on plesk while working on localhost

What I'm trying to do:
I'm trying to make a api that saves images. I'd send a post request to the api with the image in body and it saves to the static folder 'public/images'.
Problem: I tried to do this on localhost and it works perfectly. I've got the cross-origin error's before but I've fixed them. After I hosted the api on plesk, it doesn't save the image, or send a error message back. I've checked the logs on plesk and it says that it received the post request. but it's not doing anything with it.
front-end code on client-side (hosted on plesk):
const formData = new FormData();
var fileField = document.querySelector('input[type="file"]');
formData.append('image', fileField.files[0]);
const result = await fetch('https://cdn.dhulun.com/upload25single', {
method: 'POST',
body: formData
}).then(res => res.json())
if (result.status === "ok") {
console.log("Success");
window.location.href = '/';
} else if (result.status === "error") {
console.log("error", result.error)
} else {
console.log("Something went wrong...")
}
back-end code on api (hosted on plesk):
const express = require('express');
const multer = require('multer');
const path = require('path');
const dotenv = require('dotenv');
const mongoose = require('mongoose');
const cors = require('cors')
dotenv.config();
// CONNECT TO DATABASE
async function connectDB() {
await mongoose.connect(process.env.DB_CONNECT,
{ useNewUrlParser: true, useUnifiedTopology: true },
() => {
console.log("Connected to Portal Base [Server]")
});
}
connectDB();
var Media = require('./models/media')
// INIT APP
const app = express();
app.use(cors())
// STATIC FILES
app.use(express.static(__dirname + '/public'));
app.use('/image', express.static('./public/images'))
// RULES
// INIT MULTER
// Storage Engine
const storage = multer.diskStorage({
destination: './public/images',
filename: (req, file, cb) => {
return cb(null, `${file.fieldname}_${Date.now()}${path.extname(file.originalname)}`)
}
})
const upload = multer({
storage: storage,
limits: { fileSize: 8000000 },
})
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html')
});
app.post('/upload25single', upload.single('image'), async(req, res) => {
var image_url = `http://localhost:2525/image/${req.file.filename}`;
console.log({
status: 'ok',
image_url: image_url,
})
res.json({
status: 'ok',
image_url: image_url,
});
/* var location = req.body.location;
var category = req.body.category;
var sourceby = req.body.sourceby;
var tags = req.body.tags;
const media = new Media({
url: image_url,
location: location,
category: category,
source_by: sourceby,
tags: tags
});
try {
const saved = await media.saved();
res.json({
status: 'ok',
image_url: image_url,
});
} catch (error) {
res.json({
status: 'error',
err: error,
});
}
*/
})
function errHandler(err, req, res, next) {
if (err instanceof multer.MulterError) {
res.json({
status: 'error',
err: err.message
})
}
}
// ERROR HANDLING
app.use(errHandler)
app.listen(process.env.PORT || 2525, () => console.log("Server Started..."));
I get this error on the browser console (hosted on plesk): Uncaught (in promise) SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
When i click the code line number in the log i got sent to this line:
console.log("Something went wrong...")
EDIT: I got suggested to turn res.json() to res.text() and i got this:
<p>iisnode encountered an error when processing the request.</p><pre style="background-color: eeeeee">HRESULT: 0x6d
HTTP status: 500
HTTP subStatus: 1013
HTTP reason: Internal Server Error</pre><p>You are receiving this HTTP 200 response because <a href=https://github.com/tjanczuk/iisnode/blob/master/src/samples/configuration/web.config>system.webServer/iisnode/#devErrorsEnabled</a> configuration setting is 'true'.</p><p>In addition to the log of stdout and stderr of the node.exe process, consider using <a href=http://tomasz.janczuk.org/2011/11/debug-nodejs-applications-on-windows.html>debugging</a> and <a href=http://tomasz.janczuk.org/2011/09/using-event-tracing-for-windows-to.html>ETW traces</a> to further diagnose the problem.</p><p>The last 64k of the output generated by the node.exe process to stderr is shown below:</p><pre style="background-color: eeeeee">(node:7696) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.
Using Node.Js: Express & Multer

Getting cannot POST / error in Express

I have a RESTful API that I am using postman to make a call to my route /websites. Whenever I make the call, postman says "Cannot POST /websites". I am trying to implement a job queue and I'm using Express, Kue(Redis) and MongoDB.
Here is my routes file:
'use strict';
module.exports = function(app) {
// Create a new website
const websites = require('./controllers/website.controller.js');
app.post('/websites', function(req, res) {
const content = req.body;
websites.create(content, (err) => {
if (err) {
return res.json({
error: err,
success: false,
message: 'Could not create content',
});
} else {
return res.json({
error: null,
success: true,
message: 'Created a website!', content
});
}
})
});
}
Here is the server file:
const express = require('express');
const bodyParser = require('body-parser');
const kue = require('kue');
const websites = require('./app/routes/website.routes.js')
kue.app.listen(3000);
var app = express();
const redis = require('redis');
const client = redis.createClient();
client.on('connect', () =>{
console.log('Redis connection established');
})
app.use('/websites', websites);
I've never used Express and I have no idea what is going on here. Any amount of help would be great!!
Thank you!
The problem is how you are using the app.use and the app.post. You have.
app.use('/websites', websites);
And inside websites you have:
app.post('/websites', function....
So to reach that code you need to make a post to localhost:3000/websites/websites. What you need to do is simply remove the /websites from your routes.
//to reach here post to localhost:3000/websites
app.post('/' , function(req, res) {
});

How to store email in variables and send it with node.js

const functions = require('firebase-functions');
var nodemailer = require('nodemailer');
var transporter=nodemailer.createTransport('smtps://username#gmail.com:password#smtp.gmail.com');
exports.sendMail=functions.https.onRequest((req,res)=>{
var mailOptions={
to: 'sender#gmail.com',
subject: 'Test Mail',
html: 'Testing with Node.js'
}
transporter.sendMail(mailOptions,function(err,response){
if(err)
{
res.send('Mail not sent');
console.log(err);
}
else{
res.send('Mail sent');
}
});
});
I want to send email to various persons over time. I want to change the to: address in this code dynamically. So how to get a particular(sendermailid) variable from another javascript file and send to that person. My folders are located as below the picture.
How to get the variable from assmt.js to index.js(cloud function js).
You need to set up an express server who is listening our other JS aplication like this :
var express = require('express');
var app = express();
Now you can listen from another app on specified port :
var port = process.env.PORT || 8080;
app.listen(port);
console.log("App listening on port " + port);
Finally you have to intercept http post request to send your mail and get user info from the request :
app.post('/api/sendmail', function(req, res) {
var mail = {
from: req.body.user.emailFrom,
to: req.body.user.emailTo,
subject: "your subject",
html: "<p>email body</p>"
}
transporter.sendMail(mail, function(error, response){
if(error){
console.log("Error!");
console.log(error);
res.send(JSON.stringify(error));
}else{
res.send(JSON.stringify(response));
console.log("Success!")
transporter.close();
}
}
Your server is now ready you can start it with :
node serverName.js
And in your other js file ( assmt.js ) you send the http request with parameter :
send(user : User) {
let body = {user};
this.httpClient.post('http://localhost:8080/api/sendconge', body)
.subscribe(function(data) {
console.log(data);
});
}

io.connect: io is not defined but socket.io is loaded

I have built a node.js server that provides a client.html page with a list of messages from a mysql db. I can't make it work using an ajax call.
The client.html page is this:
<time></time>
<div id="container">Loading ...</div>
<script src="http://oclock.dyndns.org:8000/socket.io/socket.io.js"></script>
<!--<script src="socket.io/socket.io.js"></script>-->
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
// create a new websocket
var socket = io.connect('http://oclock.dyndns.org:8000');
// on message received we print all the data inside the #container div
socket.on('notification', function (data) {
var msgs = '<div>';
$.each(data.flashmsgs,function(index,flashmsg){
msgs += "<b>Messaggio inviato da " + flashmsg.created_by + "</b><br>";
msgs += flashmsg.testo;
});
msgs += '</div>';
$('#container').html(msgs);
$('time').html('Last Update:' + data.time);
});
</script>
and the code for the ajax call is the following:
(function nodeLoader(){
$.ajax({
url: "client.html",
method: "get",
data: {hk: hk },
success: function(data){
$('#messaggi').html(data);
}
});
})();
The socket.io code is loaded but I get an error on io.connect: io is not defined. Same issue if i change the url from client.html to http://oclock.dyndns.org:8000 (the url of the node.js server that is listening for requests).
Any help is appreciated!
EDIT:
server.js
var hwkey;
var app = require('http').createServer(handler),
io = require('socket.io').listen(app),
url = require('url'),
fs = require('fs'),
mysql = require('mysql'),
connectionsArray = [],
connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'flipper',
database: 'oclock',
port: 3306
}),
POLLING_INTERVAL = 3000,
pollingTimer;
// If there is an error connecting to the database
connection.connect(function(err) {
// connected! (unless `err` is set)
if (err) {
console.log(err);
}
});
// creating the server ( localhost:8000 )
app.listen(8000);
function handler(req, res) {
var origin = (req.headers.origin || "*");
if (req.method.toUpperCase() === "OPTIONS"){
res.writeHead(
"204",
"No Content",
{
"access-control-allow-origin": origin,
"access-control-allow-methods": "GET, POST, PUT, DELETE, OPTIONS",
"access-control-allow-headers": "content-type, accept",
"access-control-max-age": 10, // Seconds.
"content-length": 0
}
);
return( res.end() );
}
console.log("INCOMING REQUEST: "+req.method+" "+req.url);
req.parsed_url = url.parse(req.url, true);
var getp = req.parsed_url.query;
hwkey = getp.hk;
fs.readFile(__dirname + '/client.html', function(err, data) {
if (err) {
console.log(err);
res.writeHead(500);
return res.end('Error loading client.html');
}
res.writeHead(
200,
{
"access-control-allow-origin": origin,
"content-length": data.length
}
);
res.end(data);
});
}
function pollingLoop(){
// Doing the database query
var query = connection.query('SELECT id, testo, created_by FROM flashmsgs WHERE hwk="'+hwkey+'" AND letto="0"'),
//var query = connection.query('SELECT max(id), testo, created_by FROM flashmsgs'),
flashmsgs = []; // this array will contain the result of our db query
// setting the query listeners
query
.on('error', function(err) {
// Handle error, and 'end' event will be emitted after this as well
console.log(err);
updateSockets(err);
})
.on('result', function(flashmsg) {
// it fills our array looping on each user row inside the db
flashmsgs.push(flashmsg);
})
.on('end', function() {
// loop on itself only if there are sockets still connected
if (connectionsArray.length) {
pollingTimer = setTimeout(pollingLoop, POLLING_INTERVAL);
updateSockets({
flashmsgs: flashmsgs
});
} else {
console.log('The server timer was stopped because there are no more socket connections on the app')
}
});
};
// creating a new websocket to keep the content updated without any AJAX request
io.sockets.on('connection', function(socket) {
console.log('Number of connections:' + connectionsArray.length);
// starting the loop only if at least there is one user connected
if (!connectionsArray.length) {
pollingLoop();
}
socket.on('disconnect', function() {
var socketIndex = connectionsArray.indexOf(socket);
console.log('socketID = %s got disconnected', socketIndex);
if (~socketIndex) {
connectionsArray.splice(socketIndex, 1);
}
});
console.log('A new socket is connected!');
connectionsArray.push(socket);
});
var updateSockets = function(data) {
// adding the time of the last update
data.time = new Date();
console.log('Pushing new data to the clients connected ( connections amount = %s ) - %s', connectionsArray.length , data.time);
console.log(hwkey);
// sending new data to all the sockets connected
connectionsArray.forEach(function(tmpSocket) {
tmpSocket.volatile.emit('notification', data);
});
};
console.log('Please use your browser to navigate to http://localhost:8000');
Okay, I misunderstood at first. I just investigated your live app and it appears your ajax call is pulling down an entire html document.
If you're loading markup via ajax and then inserting into the existing page, you don't want a full HTML document. Just send down the body content.
Also, the socket.io script reference should ideally be on the parent page, not the page loaded via ajax.

Categories