AJAX broken, POST route 404 (Not Found) - node.js

I've been working on this for a couple of days. I'm certain its something really stupid, but I'm at the end of my sanity.
The public files are set up properly.
Error Message:
POST 127.0.0.1:8080/api/pvtToggle 404 (Not Found)
Front End HTML:
<li class="list-group-item list-group-item-dark">
<div class="row">
<div class="col-md-4"><strong>Heating:</strong> {{#if heating}} {{this.heating}} {{else}} N/A {{/if}}</div>
<div class="col-md-4"><strong>Cooling:</strong> {{#if cooling}} {{this.cooling}} {{else}} N/A {{/if}}</div>
<div class="col-md-4">
<input type="checkbox" id="pvt{{this.id}}" checked="{{this.private}}" onchange="togDefine({{this.id}}, {{this.private}});" data-toggle="toggle" data-on="Private" data-off="Public" data-onstyle="success" data-offstyle="danger" />
</div>
</div>
AJAX Call:
// Private-Public toggle
let togDefine = (id, pvt) => {
$.ajax({
type: "POST",
url: "/api/pvtToggle",
data: {
id: id,
newState: (pvt === 'true') ? false : true
},
success: function(text) {
if (text === 'ok') {
pvtSuccess(id, pvt);
} else {
console.log('updatePvt failed');
}
}
});
};
let pvtSuccess = (id, pvt) => {
$('#pvt' + id).attr('checked', (pvt === 'true') ? 'false' : 'true');
};
Back End:
//TOGGLE Private vs Public PROPERTY
app.put('/api/pvtToggle/', isAuthenticated, function(request, response) {
db.Prop.update({
private: request.params.newState
}, {
where: {
id: request.params.id
}
}).then(data => {
response.send('ok');
}).catch(error => {
console.log(error);
});
});
Please help me figure out why the request isn't working properly. :D

Your endpoint is app.put, implying it responds to a PUT request,
but your ajax/fetches are making POST requests.

Related

how to paginate through user notifications without mixing them up?

i'm working on a MERN app where the user can receive notifications on certain events, the user can then open the notification page where he can view his notifications, the issue that i have is the notifications have a "seen" state, the notifications that aren't seen will always be on top of the notification results..but say the user clicks on a notification which sets it as seen and then paginates further down the notification list by clicking on "show more" btn, he will find that earlier notification waiting for him in the bottom, basically it's duplicating..how can i fix this?
express controller for notifications
router.get("/", verifyUser, (req, res) => {
let userId = res.locals.user._id; //from the verify user MW, unrelated to question
let pageNum = req.query.page;
const options = {
page: pageNum,
limit: 8,
sort: { seen: 1, createdAt: -1 }
};
Notification.paginate({ receiver: userId }, options, (err, result) => {
if (err) {
console.log(err);
res.sendStatus(400);
} else {
res.status(200).json(result);
}
})
})
react
function Notifications(){
let { texts } = useContext(LangContext);
let [notificationsList, setNotificationsList] = useState([]);
let [isPending, setIsPending] = useState(true);
let [notiPage, setNotiPage] = useState(1);
let [hasNext, setHasNext] = useState(false);
function getNotifications() {
axios.get(`/api/notification?page=${notiPage}`).then(result => {
console.log(result);
setNotificationsList([...notificationsList, ...result.data.docs]);
if (result.data.hasNextPage) {
setNotiPage(result.data.nextPage);
setHasNext(true);
} else {
setHasNext(false);
}
setIsPending(false);
}).catch(err => {
console.log(err);
setIsPending(false);
})
}
//update notification seen status on the backend as well as on the front end
function toggleNotificationView(id, seen) {
let viewStatus = !seen;
axios.put(`/api/notification/${id}`, { seen: viewStatus }).then(result => {
console.log(result);
let notiArray = [...notificationsList];
let index = notiArray.findIndex(noti => {
return noti._id == id;
})
let editedNoti = notiArray[index];
editedNoti.seen = viewStatus;
notiArray.splice(index, 1, editedNoti);
setNotificationsList(notiArray);
}).catch(err => {
console.log(err);
})
}
return <div>
<div className="d-flex flex-column justify-content-center align-content-center my-3">
{notificationsList.map(notification => {
return (<div key={notification._id} id={notification._id} className="w-70 mx-auto">
<div className={`d-flex justify-content-between ${!notification.seen ? "new-notification" : ""}`}>
<a className="text-decoration-none text-dark" href={notification.srcInfo.link}>
<div className={`d-flex justify-content-start align-items-center`}>
<img src={notificationBell} width={100} height={100} />
<p className="text-start fs-4 mx-4" >{parseNotification(notification)}</p>
</div>
</a>
<div className="noti-dropdown noselect align-self-start">
<i onClick={toggleDropDown} className="bi bi-three-dots-vertical fs-4"></i>
<ul className="noti-dropdown-options px-0 fs-5">
<li onClick={() => { deleteNotification(notification._id) }}>{texts.deleteNotification}</li>
<li onClick={() => { toggleNotificationView(notification._id, notification.seen) }}> {notification.seen ? texts.markNotificationNotSeen : texts.markNotificationSeen}</li>
</ul>
</div>
</div>
<hr className="text-main" />
</div>)
})}
</div>
{hasNext && <h4 onClick={getNotifications} className="mx-auto text-center text-main text-decoration-underline"><span className="cursor-pointer">{texts.notificationShowMore}</span></h4>}
</div>
}
the problem is happening because i'm sorting by seen while paginating, what can i do about this?

NodeJS render html file with form not working on angular side

I am using ExpressJS with EJS template view engine. I am trying to show an HTML file on the angular component, but the form tag and its child input tag do not work on the angular side. They show only label data.
On NodeJS
agreementController.js
exports.getAgreementHtml = async (request, response, next) => {
const params = request.query
let reqPath = path.join(__dirname, '../agreements');
var agreementObj = {
user: { email: "example#gmail.com" }
}
// render domestic rent html
ejs.renderFile(reqPath + '/domestic_rent.ejs', agreementObj, {}, function (err, str) {
if (err !== null) {
responseObj.status = errorCodes.DATA_NOT_FOUND
responseObj.message = language.getMessage('NO_RECORD_FOUND')
response.send(responseObj)
return
}
responseObj.status = errorCodes.OK
responseObj.data = str
response.send(responseObj);
return;
});
}
domestic_rent.js
<form>
<div class="form-group">
<p><%= user.email %></p>
<div class="col-sm-offset-2 col-sm-10">
<input type="text" class="form-control" id="inputEmail3" placeholder="test" required name="test">
</div>
</div>
</form>
On Angular 8 Side
agreement-show.component.ts
getAgreementData() {
const params = {
id: this.agreementId
};
this.agreementService.getAgreementHtml(params).subscribe(
(result) => {
console.log('result agreement data::: ', result);
if (result.status !== 200) {
this.commonService.change.emit({ status: 'error', message: 'unknown error' });
return;
}
this.someHtml = result.data;
return;
}, (error) => {
console.log('error', error)
this.commonService.change.emit({ status: 'error', message: error.message });
}
);
}
agreement-show.component.html
<div [innerHTML]="someHtml"></div>
Output Attachment
By using ElementRef function we can add html runtime.
Please use following step:
#ViewChild('showitems') showitems: ElementRef;
const elemt: HTMLElement = this.showitems.nativeElement;
this.someHtml = result.data;
elemt.innerHTML = this.someHtml;

Vue Js Form post issues to server

I am building a website and I cannot find a way to send my SignUp form data to my server using post. I tried with axios but it didn't work.
This is basically how my signup page looks like
<template>
<div id = "app">
<!-- <router-view /> -->
<h1>{{ $t('signup') }}</h1>
<p>{{ $t('signupMsg') }}</p>
<b-form #submit="onSubmit" #reset="onReset" method="post" >
<b-form-group
id="input-group-1"
label-for="input-1"
>
<p1> Name: </p1>
<b-form-input
id="input-1"
v-model="form.name"
required
placeholder="Enter Name and Vorname"
></b-form-input>
</b-form-group>
<b-form-group id="input-group-2" label-for="input-2" >
<p1>{{ $t('tech') }}</p1>
<b-form-input
id="input-2"
v-model="form.technicianID"
required
placeholder="Enter assigned Technician ID"
></b-form-input>
</b-form-group>
<b-form-group id="input-group-3" label-for="input-3">
<p1> Email ID: </p1>
<b-form-input
id="input-3"
v-model="form.email"
required
placeholder="Enter assigned Email ID"
></b-form-input>
</b-form-group>
<b-form-group id="input-group-4" label-for="input-4">
<p1> {{ $t('branch') }} </p1>
<b-form-input
id="input-4"
v-model="form.branch"
required
placeholder="Enter your branch"
></b-form-input>
</b-form-group>
<!-- <b-button type="submit" > <router-link to="/requestsuccess">{{ $t('signup') }}</router-link> </b-button> -->
<b-button type="submit" >{{ $t('signup') }} </b-button>
<b-button type="reset" variant="danger">{{ $t('reset') }}</b-button>
<router-link to="/" class="btn btn-link">{{ $t('back') }}</router-link>
</b-form>
</div>
</template>
<script>
import axios from 'vue-axios'
export default {
name: 'signup',
data() {
return {
form: {
name: '',
technicianID: '',
email:'',
branch: ''
}
}
},
methods: {
onSubmit(evt) {
evt.preventDefault()
axios({
method: 'post',
url: '/insert',
data: this.form
})
.then(function (response) {
//handle success
console.log(response);
})
.catch(function (response) {
//handle error
console.log(response);
});
},
onReset(evt) {
evt.preventDefault()
// Reset our form values
this.form.name = ''
this.form.technicianID = ''
this.form.email = ''
this.form.branch = ''
// Trick to reset/clear native browser form validation state
this.show = false
this.$nextTick(() => {
this.show = true
})
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style>
</style>
This is how my index.js looks like for post
router.post('/insert', function(req, res, next) {
var item = {
name: req.body.name,
technicianID: req.body.technicianID,
email: req.body.email,
branch: req.body.branch
};
mongo.connect(url, function(err, db) {
assert.equal(null, err);
db.collection('users').insertOne(item, function(err, result) {
assert.equal(null, err);
console.log('Item inserted');
db.close();
});
});
res.redirect('../components/requestsuccess');
});
I am fairly new to this but I can't find a way to send my data to the server.
You can try this code below:
Backend: You can change your backend with this code below
router.post('/insert', function(req, res, next) {
console.log(req.body);
mongo.connect(url, function(err, db) {
db.collection('users').insertOne(req.body, function(err, result) {
if(err) return res.status(500).send(err);
return res.status(200).send(result.ops[0]);
db.close();
});
});
});
The code above only an example for simple case. If you want to add assert, then you can make sure it's working fine. If the simple code above it's working, then you can add assert.
Make sure you've been install cors on your server and add it in your app.js or server.js this code below:
app.use(cord({origin: "*"});
And then, make sure you call your endpoint use: http://. Not only localhost but http://localhost.
FrontEnd
onSubmit(evt) {
evt.preventDefault()
axios({
method: 'post',
url: '/insert', // make sure your endpoint is correct
data: this.form
})
.then(response => {
//handle success
console.log(response.data);
// do some stuff here: redirect or something you want
})
.catch(error => {
//handle error
console.log(error.data);
});
},
Make sure your endpoint is correct.
I hope it can help you.

I want to create a Search method that autodisplay some results

I'm creating a function that is looking for users in database.
I've done the server-side code, but I don't know how to display the results in the html code. I know that I have to write some JavaScript code but I don't know how
I found something on Google, but it doesn't work.
This is my route.
router.get('/search', isAuth, feedController.getSearch);
This is my controller.
exports.getSearch = (req,res,next) => {
const search = req.query.searchField;
User.find({
firstname:{
$regex: new RegExp(search)
},
}, {
_id:0,
__v:0
}, function (err,data) {
res.json(data);
}
).limit(10);
}
This is my HTML
<li>
<div class="search-box">
<form action="/search" method="GET" class="form-inline my-0 my-lg-0">
<input type="text" aria-label="Search" class="form-control mr-sm-0" onkeyup="showResults(this.value)" placeholder="Mirror-Mirror Search">
<span class="hightlight"></span>
<span class="bar"></span>
</input>
<button type="submit" class="search-btn"><i class="fas fa-search"></i></button>
</form>
</div>
<div style="position: relative; width:100%; top:-1px;">
<div class="border" id="search-results"></div>
</div>
</li>
And this is what I found on Google
var showResults = debounce(function(arg) {
var value = arg.trim();
if(value == "" || value.length <=0)
{
$("#search-results").fadeOut();
return;
}
else {
$("#search-results").fadeIn();
}
var jgxh = $.get('/controllers/feed/getSearch?searchField=' + value, function(data) {
$("#search-results").html("");
})
.done(function(data){
if(data.length === 0) {
$("#search-results").append('<p class="lead text-center mt-2">No results</p>');
} else {
data.forEach(x => {
$("#search-results").append('<a href="#> <p class="m-2 lead>' +x.firstname+' '+x.lastname + '</p></a>')
});
}
})
.fail(function(err){
console.log(err);
})
},200)
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this;
args = arguments;
var later = function () {
timeout = null;
if(!immediate) func.apply(context,args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if(callNow) func.apply(context,args);
};
};
I expected to autodisplay the results, but It doesn't work. I want to search in my database either for 'firstname' or 'lastname', I hope you can help me, thank you!

NodeJS - AJAX POST 404 (Not Found)

I am trying to send values from one file to another on click of items displayed.
While doing so, I am getting the error:
POST http://localhost:4000/todo/addToCart 404 (Not Found) jquery-3.3.1.js:9600
My app.js file:
//More codes above to set-up express and all
app.use(express.static('./public'));
todoController(app); //give todocontroller the reference to express
app.listen(4000); //listen on a port
console.log('server is running');
Controller:
module.exports = function(app) {
app.get('/todo', function(req, resp) {
Todo.find({}, function(err, data) {
if (err) throw err;
console.log('get method');
resp.render('todo', {
todos: data
});
});
});
//Few More Code
app.post('/todo', urlencodedParser, function(req, resp) {
console.log('post method');
resp.render('addToCart', {
data: req.body
});
});
};
Model for data interaction:
$('li').on('click', function() { //when user clicks on an item in the list
var item = $(this).text().replace(/ /g, "-"); //traps the item user clicked on
alert(item);
$.ajax({
type: 'POST',
url: '/todo/addToCart', //+item append that item to the url
success: function(item) {
location.reload(); //refresh the page
}
});
});
Parent ejs:
<div id="todo-table">
<form id="todoForm" method="post" action="/todo">
<input type="text" name="item" placeholder="Add new Item..." required />
<button type="submit">Add Item</button>
<ul>
<% for (var i=0;i<todos.length; i++){ %>
<li>
<%=todos[i].item%>
</li>
<% } %>
</ul>
</form>
</div>
Child ejs(to which I need to re-direct):
<div id="itemSelect">Selected Item:
<form id="addToCart" method="post" action="/addToCart">
<button type="submit" id="btnCheckOut">Check out</button>
<%=data.item%>
</form>
</div>
Please help. I am new, kindly point out my mistake.
Many thanks.
The route you created on your nodejs server here:
app.post('/todo', urlencodedParser, function (req, resp) {
console.log('post method');
resp.render('addToCart', { data: req.body });
});
Matches all the POST requests made to the /todo endpoint, not the /todo/addToCart which doesnt exist. This is why you obtain a 404.
Your ajax request should be like so:
$('li').on('click', function () {
var item = $(this).text().replace(/ /g, "-");
alert(item);
$.ajax({
type: 'POST',
url: '/todo', // 'addToCart' has been removed from the path
success: function (item) {
location.reload();
}
});
});

Resources