I have an array that is generated on page, saved as an variable. How to to send it with a POST to db (mongodb, node, express) - node.js

A node, express, mongodb question.
I have a webpage, with a some JS-code. The user types some things into the my form and then they can generate a table with data. Before the table is printed to the user the data as saved as a variable (Array). The array itself is named obj.invoices.
I can easily save the data from the form to the DB using the "name". When I use it shows up in the req.body, which i then can use in my controller and save it to the DB.
But how do i pass the generated variable (obj.invoices) from the page so that it will follow along in the POST and shows up in the req.body?
As for now the array isn't parsed so i cant build a function in express/mongoose to save the data to the DB.

I solved it but I'm quite sure this is a bad solution.
When finished generating the array I run this function,
function showArray() {
var json_data = JSON.stringify(myArray);
document.getElementById('showArray').innerHTML = json_data;
}
This convert the array to string, and then post it into a input within my form;
<div class="field">
<div class="control">
<textarea id="showArray" class="textarea is-info" type="text" name="ArrayToDb"></textarea>
</div>
</div>
So when i submit my form the array as a string is posted with the req.body. Then in my controller.js for the app I convert the string back to an array;
let jsonArray = JSON.parse(req.body.ArrayToDb)
and then i save it to the DB
newLan.fakturor = jsonArray;
newLan.save(function (err) {
console.log(newLan._id)
});
Like I said, this is most likely a really bad way to do it but it works for me, for now.

Related

Data passed to Handlebars not showing

I want to display items from the database which I already log the result to the console. The console displays the result. but handlebars not displaying data.
This is controller
exports.createCategory = function(req, res, next){
knex('product_category')
.select()
.then(function(errors, result){
res.render('administration/category', { result, errors });
});
}
This is my router
router.get('/category', adminControllers.createCategory);
and this is my handlebar
<div class="col-md-4 col-lg-4">
{{#each result}}
<h1>{{category_name}}</h1>
{{/each}}
</div>
Just do debugging 101.
Add debug prints and check that you get correct data from DB and that it even executes.
Add to template some field to show you error too. Now if error is returned from query, nothing is shown.
Also add some static test attribute that you pass to template and print it to make sure that you are using handlebars template correctly.
I later got it.
Its the knex query.
after studying the knex docs and some online resources, I discovered I can also do this
knex('table').then(function(result)){
res.render('/', {result});
}
but I don't why this didn't work
knex('table').select().then(function(result)){
res.render('/', {result});
}

Get Request for data in MongoDB with ExpressJs

I am new to nodejs/web app and I am trying to get data out from MongoDB.
My mongoDB has documents under collection "a"
{_id:("1"), "Question":"mcq1", "Answer":"one", "Keyword":"CLASS"}
{_id:("2"), "Question":"mcq2", "Answer":"two", "Keyword":"CLASS"}
{_id:("3"), "Question":"mcq3", "Answer":"three", "Keyword":"OVERLOAD"}
{_id:("4"), "Question":"mcq4", "Answer":"four", "Keyword":"OODP"}
I want to extract the data "Question": field_value, "Answer":field_value out using nodejs -> expressjs through a button and textbox form using the unique Keyword and to be displayed in a table form as below.
<tr>
<td><%= Question %></td>
<td><%= Answer %> </td>
</tr>
I have been able to get what i want with the monogodb shell using
db.a.find({"Keyword":CLASS},{"Question":1,"Answer":1,_id:0})
Currently the textbox and button onclick codes are below.
Input Keyword to search: <input type="text" id="searchBtn" value="">
<button type="button" onclick="alert(document.getElementById('searchBtn').value)">Click me!</button>
How can i extract the Question and Answer with the button click?
Using db.a.find({"Keyword":CLASS},{"Question":1,"Answer":1,_id:0})
i want to get a table in the form of
Question, Answer,Keyword
mcq1, one, CLASS
mcq2, two, CLASS
If you do a db query based on that keyword you'll get the occurrences in mongo, so you can do a form(GET/POST) field with the input and the button you already have. This will be caught in your express code as a route, there you can implement some basic code filling your search needs and the return value will be some simple data or an array if multiple match.
This is a basic search that one user (Miqe) once taught me here, first you need the query (or you can just put directly there) and later search in the mongo. But pay attention that your callback function will return the result, here is just a console.log() after returning the values you can assign them to a variable and pass through a template engine rendering in the html in the desire format.
query = {username: username, password: password}
dbo.collection('Users').find(query, function(err, user){
if(err) throw new Error(err);
if(!user)
console.log('Not found');
else
console.log('Found!');
})
Here is just the code to find in a collection named Users, you still need to join with the route and do a connection to the DB.
I'll leave a link who helped me a lot! The mongo documentation is still a good start too.
https://www.w3schools.com/nodejs/nodejs_mongodb_query.asp

How to pass a query string from Angular to ExpressJS

I am using Express + MongoDB native driver (NOT MONGOOSE), and I would like to create an API endpoint that can 'filter' through my results.
Structure:
In my component, I have 30 "filters" (select boxes), and I have 5000+ documents in my 'xxxx' collection being displayed in a catalog fashion. Every time the user clicks submit, I would like to send a query to MongoDB and update my results to my catalog. This can be done with services + subscriptions, that's fine. My issue is creating the API endpoint that can consume queries.
I have an Angular component which has about 30 select boxes, where each value is a fragment of a query string.
Consider the following select boxes:
<select name="test" form="myform">
<option value="{'name': 'Volvo'}">Volvo</option>
<option value="{'name': 'Honda'}">Honda</option>
</select>
<select name="test2" form="myform">
<option value="{'model': 'ILX'}">ILX</option>
<option value="{'model': 'MDX'}">MDX</option>
</select>
When the form is submitted, the following query should be passed to express:
/filter/test/{{'name': 'Honda'},{'model': 'ILX'}}
This is the ('ideal') code for my express endpoint (this produces errors):
router.get('/filter/test/:query', function(req, res) {
var collection = db.get().collection('xxxxxx')
collection.find({ query }).toArray(function(err, docs) {
res.send(docs)
})
})
Questions:
1. How can I pass a query (or string) from this form to express? (I believe it's the API endpoint in my submit button's action markup)
2. How do I construct this API endpoint correctly?
3. Is something like this safe/secure in production? If not, how do I secure it or what is a better implementation?
It depends on what you are developing. If your data is not too much sensitive put it in url params and send a get call and if data is sensitive use a post or patch call. This is what rest api does for deletions use delete call and do not submit the form directly to rest api try to use ajax to hit api behind the scenes.
Create a form like this
<form action="/filter/test/{{test}}/{{model}}">
<select name="test" [(ngModel)]="test" form="myform">
<option [value]=" 'Volvo'">Volvo</option>
<option [value]="'Honda'">Honda</option>
</select>
<select name="test2" [(ngModel)]="model" form="myform">
<option [value]="'ILX'">ILX</option>
<option [value]="'MDX'">MDX</option>
</select>
</form>
And read it in api like this
router.get('/filter/test/:test/:model', function(req, res) {
var collection = db.get().collection('xxxxxx')
collection.find({ test : req.params.test, model : req.params.model }).toArray(function(err, docs) {
res.send(docs)
})
})
If you have multiple fields and you have a case user will fill up some of them and some not use patch/post as my suggestion create your angular model like this
let data = {
field1: "",
field2: "",
...
}
Now use field1, field2 and rest in you form models and using ajax call post/patch this data object directly to rest end point you dont need url params now extract and verify them in req.body you will find them. For this you need to add a json parser in nodejs.

Uploading an image to mongodb is not saving

I am trying to upload an image to my mongodb database but it is not saving. My mongoose schema is like this:
var schema = mongoose.Schema({
title: String,
picture: { data: Buffer, contentType: String }
});
I noticed another thing that I am sending the picture like this :
picture: 'C:\\fakepath\\6b512998.jpg' This entire thing is reaching my server as a string after that my database doesn't save the picture but only title gets saved.
router.post('/post', function(req, res) {
Post.create(req.body, function(err, post) {
});
});
I am not getting any errors on my console.
edit: I was thinking it was more of a schema fault. Here is the form.
I am not sure about middle wear. How do I check that? Sorry I am still new and learning new everyday.
new.html:
<form class="imageform" action="posts" method="/post" accept="image/gif,image/jpeg">
<input type="text" name="title">
<input type="file" name="picture"><br>
<button type="submit"> Submit form </button>
</form>
Actually you need to convert your image files to another format, before saving them to the database,
If your files are actually less than 16 mb, please try using this Converter that changes the image of format jpeg / png to a format of saving to mongodb, and you can see this as an easy alternative for gridfs ,
please check this github repo for more details...

Utilizing Bootstrap's typeahead as a search function

I've got typeahead working just fine, but I am too inexperienced with the Javascript to understand how to turn the typed results into a link.
<input type="text"
class="span3"
data-provide="typeahead"
placeholder="City Search:"
data-items="6"
autocomplete="off"
data-source=["Neuchatel","Moutier"]">
So, I really just want to know how to turn the strings from data-source into links to other pages. Hopefully this is fairly simple.
thanks!
You can turn the strings into links easily..
<input type="text" data-provide="typeahead" data-source="["/foo.html","http://www.google.com","/about.html"]">
Are you also looking to take the link from the input and then navigate to the selected page?
EDIT: Navigate to item selected in typeahead..
In this case you'd define an object map that contain keys (label) and values (url) like..
var data = {
"login":"/login",
"home":"/",
"user":"/user",
"tags":"/tags",
"google":"http://google.com"
};
Then you'd initiate the typeahead. The source and updater functions would be defined to handle 1) creating the typeahead data source array from the map object, and 2) navigate to the appropriate url when an item is selected..
$('.typeahead').typeahead({
minLength:2,
updater: function (item) {
/* navigate to the selected item */
window.location.href = data[item];
},
source: function (typeahead, query) {
var links=[];
for (var name in data){
links.push(name);
}
return links;
}
});
Demo on Bootply

Resources