How to pass data from div like from input in nodejs - node.js

I want to pass data from quill editor but problem is that editor is div. In which is another div created after pageload.
Handlebars
<!-- Create the editor container -->
<div id="editor" name="body">
<div class="another div created after page load">
</div>
</div>
But problem is that i cant probably pass data from div it needs to be input but i have no idea how can i make it.
Controller for articles
exports.articleAdd = function (req, res) {
let article = new Article();
article.heading = req.body.heading;
article.author = req.user.firstname;
article.body = req.body.body;
article.save(function (err) {
if (err) {
console.log(err);
return;
} else {
res.redirect('/');
}
});
}

Its solved on their official site. https://quilljs.com/playground/#form-submit

Related

How to call an html form action attribute as method in vuejs?

I'm try to create an app that take a image using drag and drop method, and immediately do the action specified in the form that containing it.
index.ejs
<form class="form"
id="form"
method="POST"
action="/images/upload" <-- Llamar a esta acción
enctype="multipart/form-data"
#dragover.prevent
v-cloak #drop.prevent="addFile"
>
</form>
I tried this way, the result is capture the object but I don't know how to send the specified action.
index.ejs
var app = new Vue({
el: '#form',
methods:{
addFile(e) {
file = e.dataTransfer.files[0]
console.log(file)
/// Llamar a action
},
})
Finally, it is the rout that is managed the action form.
router.post('/images/upload', (req, res) => {
uploadImage(req, res, (err) => {
if (err) {
err.message = 'The file is so heavy for my service';
return res.send(err);
}
console.log(req.file);
res.send('uploaded');
});
});
Thanks for your assist.
You can use #submit.prevent for calling a method for your action.
Now for your question part:
As soon as you successfully drag and drop the image, either you can click the submit button with the help of jQuery or refs dynamically and call the action method or you can direct call the method of your action.
<template>
<div>
<form class="form" id="form" method="POST" #submit.prevent="YOUR_METHOD_GOES_HERE" enctype="multipart/form-data" #dragover.prevent v-cloak #drop.prevent="addFile">
</form>
</div>
</template>
<<script>
export default {
methods: {
YOUR_METHOD_GOES_HERE(){
// place your action logic here
}
},
}
</script>

Can't Edit and Update properties with form Reactjs and MongoDB

So I'm using Nodejs, MongoDB and Reactjs
and I'm trying to Edit properties of projects.
I have multiple projects and when I want to edit properties of one I can't do it. We can access to properties inside inputs, we can see Title and Type but can't even delete, write, he access to properties by its ID but then I can't change it, I guess I have multiple problems here than.
I'll write here my server code, and my Edit/Update project page and a gif with an example when I say that I can't even change anything on inputs.
My server code:
//Render Edit Project Page byId
app.get('/dashboard/project/:id/edit', function(req, res){
let id = req.params.id;
Project.findById(id).exec((err, project) => {
if (err) {
console.log(err);
}
res.json(project);
});
}
//Update Projects Properties byId
app.put('/dashboard/project/:id/edit', function(req, res){
var id = req.params.id;
var project = {
title: req.body.title,
typeOfProduction: req.body.typeOfProduction
};
Project.findByIdAndUpdate(id, project, {new: true},
function(err){
if(err){
console.log(err);
}
res.json(project);
})
};
My React Component Edit Project Page
import React, { Component } from 'react';
import { NavLink } from 'react-router-dom';
import './EditProject.css';
class EditProject extends Component {
constructor(props){
super(props);
this.state = {
//project: {}
title: '',
typeOfProduction: ''
};
}
inputChangedHandler = (event) => {
const updatedProject = event.target.value;
}
componentDidMount() {
// console.log("PROPS " + JSON.stringify(this.props));
const { match: { params } } = this.props;
fetch(`/dashboard/project/${params.id}/edit`)
.then(response => { return response.json()
}).then(project => {
console.log(JSON.stringify(project));
this.setState({
//project: project
title: project.title,
typeOfProduction: project.typeOfProduction
})
})
}
render() {
return (
<div className="EditProject"> EDIT
<form method="POST" action="/dashboard/project/${params.id}/edit?_method=PUT">
<div className="form-group container">
<label className="form--title">Title</label>
<input type="text" className="form-control " value={this.state.title} name="title" ref="title" onChange={(event)=>this.inputChangedHandler(event)}/>
</div>
<div className="form-group container">
<label className="form--title">Type of Production</label>
<input type="text" className="form-control " value={this.state.typeOfProduction} name="typeOfProduction" ref="typeOfProduction" onChange={(event)=>this.inputChangedHandler(event)}/>
</div>
<div className="form-group container button">
<button type="submit" className="btn btn-default" value="Submit" onClcik={() => onsubmit(form)}>Update</button>
</div>
</form>
</div>
);
}
}
export default EditProject;
Erros that I have:
1- DeprecationWarning: collection.findAndModify is deprecated. Use findOneAndUpdate, findOneAndReplace or findOneAndDelete instead.
2- Inputs can't change
3- When click "Update" button:
I think your update override the entire object because you forgot the $set operator. This is the operator to change only the atributtes of an object and not the entire object replacing!
Example:
Model.update(query, { $set: { name: 'jason bourne' }}, options, callback)
First of all, concerning the deprecation warning, you need to change the method findAndModify (As I do not see it here, I guess you're using it elsewhere, or maybe one of the methods you use is calling it) by one of the suggested methods and change your code accordingly.
Then, you need to learn about React and controlled components : https://reactjs.org/docs/forms.html
You need to set the component's state in your onChange handler, such as :
this.setState({
title: event.target.value // or typeOfProduction, depending on wich element fired the event
});
This is called a controlled component in React.
Concerning the response body you get when clicking on Update button, this is actually what you asked for :
res.json(project);
returns the project variable as a JSON file, which is displayed on your screenshot.
See this question for more information about it : Proper way to return JSON using node or Express
Try replace "value" in input tag with "placeholder"

how can i retrieve objectId of parse server through req.params.id

I am trying to retrieve a parse object with objectId in the show route on nodeJS. Below is my code to help you understand better.
//SHOW route
app.get("/books/:id", function(req, res) {
var Books = Parse.Object.extend("Books");
var query = new Parse.Query(Books);
query.equalTo("objectId", req.params.id);
query.find().then(function(foundBook){
res.render("show", {book: foundBook});
}, function(error) {
res.send("Error: " + error.code + " " + error.message);
});
});
Basically, The req.params.id does not return the objectID. when i try console.log(req.params.id), it returns the Title of the book stored in the database instead of the objectId which is important for linking to the /books/:id page.
Even when i try to retrieve all the objects from the database in the index route, i noticed that <%= book.get('objectId') %> is not displayed on the ejs page.
Please help me out of this. i am a beginner MEAN stack web developer but i am using parse server because the android and web applications would be sharing the same database on parse.com.
Thank You.
<% books.forEach(function(book) { %>
<div class="col-md-3 col-sm-6">
<div class="thumbnail">
<!-- this line of code gets the image content of the array and puts it in the img tag -->
<img src="<%= book.get('coverPictureLink') %>">
<div class="caption">
<h4><%= book.get('Title') %></h4>
</div>
<p>
<!-- This code adds the button and links it to the ID of the campground that was clicked on!-->
More Info
</p>
</div>
</div>
<% }); %>
</div>
Above is sample of the html page for displaying details of a particular book
I finally figured it out. The right way to retrieve object id on the html is book.id not book.get("objectId").
app.get("/books/:id", function(req, res) {
//find the book with provided ID
var Books = Parse.Object.extend("Books");
var query = new Parse.Query(Books);
query.get(req.params.id).then(function(book) {
console.log('retrieved! ' + book.id);
res.render('show', {book: book});
}, function(error) {
console.log('error occured');
res.send('could not be retrieved');
});
});
On the html file,
<p>
More Info
</p>
This is also the same if you are using node.js. with the parse server framework. Using .get('objectId') returns undefined values. Therefore you have to use.
for (i = 0; i < result.length; i++){
console.log('ID:' + result[i].id)
}

I am trying to reset the state to an empty object after every onClick occurs

I am working on a project in React. The idea is that when you search an artist an img render on the pg. Once you click the image a list of collaborating artists is rendered. You can then click a name and see that persons collabpratign artists. Here is my issue: Rather than the state clearing/resetting each time a new artist is clicked, new artists just add on to the original state. Can someone help me figure out how to clear the state so that the state clears and returns a new list of collaborators? Been stuck on this for hours. Here is the code
searchForArtist(query) {
request.get(`https://api.spotify.com/v1/search?q=${query}&type=artist`)
.then((response) => {
const artist = response.body.artists.items[0];
const name = artist.name;
const id = artist.id;
const img_url = artist.images[0].url;
this.setState({
selectedArtist: {
name,
id,
img_url,
},
});
})
.then(() => {
this.getArtistAlbums();
})
.catch((err) => {
console.error(err);
});
}
getArtistCollabs() {
console.log('reached get artist collab function');
const { artistCounts } = this.state;
// console.log(artistCounts);
const artist = Object.keys(artistCounts).map((key) => {
//kate
const i = document.createElement("div");
i.innerHTML = key;
i.addEventListener('click', () => {
this.searchForArtist(key);
})
document.getElementById("collabs").appendChild(i);
});
this.setState({});
}
//kate
renderArtists() {
const artists = this.getArtistCollabs();
}
render() {
const img_url = this.state.selectedArtist.img_url;
return (
<div>
<form onSubmit={this.handleSubmit}>
<input type='text' name='searchInput' className="searchInput" placeholder="Artist" onChange={this.handleChange} />
<input type='submit' className="button" />
</form>
<img className="artist-img" src={this.state.selectedArtist.img_url}
// kate
onClick={this.renderArtists} alt="" />
<div id="collabs">
</div>
</div>
Your problem is right here:
const artist = Object.keys(artistCounts).map((key) => {
//kate
const i = document.createElement("div");
i.innerHTML = key;
i.addEventListener('click', () => {
this.searchForArtist(key);
})
document.getElementById("collabs").appendChild(i);
What you have done here is manually create html elements and insert them into the dom. As soon as this takes place react has no control over these newly created elements. You should only manipulate the DOM like this when its absolutely necessary. Instead you should be making a new component called something like <ArtistCollaborators> and it should take in the artists as props and be what renders the code you have here into the DOM using its own render method.
This will be the React way of doing it, and allows react to be fully control of what you are rendering into the DOM.

How to access elements in the current template in meteor?

I have a template like this,
<template name = "foo">
<p id="loading" >LOADING...</p>
<p> {{theResult}} </p>
</template>
This is how I create foos,
// foos = [a, b, c, d]. With each button click I add a new item to the array
{{#each foos}}
{{> foo .}}
{{/each}}
And how a foo works,
Template.foo.created = function(){
var name = Template.currentData();
api_call(name, function(err, result){
Session.set(name, result);
});
}
Template.foo.helpers({
'theResult': function(){
var name = Template.currentData();
if(Session.get(name)) {
$("#loading").hide();
return Session.get(name);
} else {
return "";
}
}
})
So my expectation is to when the data came from the api_call, to hide "LOADING..." para, and to show the result in theResult.
The result is showing correctly. My problem is "LOADING..." is only get hidden on the top most foo. Not the other ones.
How can I fix this?
EDIT:
As suggested instead of,
$("#loading").hide();
I used,
Template.instance().$("#loading").hide();
This didn't work too :)
This is how I'd do it
Template... if theResult is undefined, the else path will be rendered.
<template name="foo">
{{#with theResult}}<p> {{this}} </p>
{{else}}<p id="loading" >LOADING...</p>
{{/with}}
</template>
Javascript... theResult is a simple Session.get call
Template.foo.helpers({
theResult: function(){
var name = Template.currentData();
return name && Session.get(name);
}
});
Thanks to Meteor templating engine, you can access a template scoped jQuery object that will only return elements within the corresponding template.
Template.foo.helpers({
'someText': function(){
var template = Template.instance();
template.$('p').changeSomeattr();
return Session.get('myPara');
}
});

Resources