Cannot read property toLowerCase of undefined using Adonis and PostgreSQL - node.js

I'm using Adonis with PostgreSQL and I am trying to implement a search where a user would be able to search through posts using the title
I have my code structured like so
<form action="{{ route('search') }}" method="GET" style="outline:none">
<input class="shadow appearance-none border-2 p-2 h-10" style="outline:none" type="text" name="q" placeholder="Search the forum" value="{{ request.input('q', '') }}">
</form>
and my controller like so
'use strict'
const Post = use('App/Models/Post')
const Database = use('Database')
class SearchController {
async index ({ view, request, response, params }) {
let posts = await Post.query()
.forIndex()
.whereRaw('lower(title) LIKE ?', params.searchString.toLowerCase())
.paginate(request.input('page', 1), 10)
return view.render('index', {
posts
})
}
}
module.exports = SearchController
However, I am getting the following error:

Instead of name='q' try name='searchString' in the form
See https://adonisjs.com/docs/4.1/request#_methods to get query string parameters in adonis

Related

Search Data not working Angular NodeJS API

i am created the search part using angular and node js. i have tested through the postman it is working fine. when connect with frond end anqular application is it not working error displayed
Failed to load resource: the server responded with a status of 404 (Not Found)
what i tried so far i attached below please check.
i tried on the url http://localhost:9001/user/findOne?first_name=kobinath
this is working well on postman but tested through the anqular didn't work. i attached the code what i tried so far.
employee.component.ts
search()
{
let name= {
"first_name" : this.first_name
};
this.http.post("http://localhost:9001/user/findOne",name).subscribe((resultData: any)=>
{
console.log(resultData);
});
}
employee.component.html
<form>
<div class="form-group">
<label>First Name</label>
<input type="text" [(ngModel)]="first_name" [ngModelOptions]="{standalone: true}" class="form-control" id="name" placeholder="Enter Name">
</div>
<button type="submit" class="btn btn-primary mt-4" (click)="search()" >Search</button>
</form>
</div>
What I noticed: With Postman you send first_name as a query parameter, but in your Angular-code you attach it to the request-body.
To achieve the equivalent of what you do in Postman, you could use the following code:
search(firstName: string) {
const params = new HttpParams().set('first_name', firstName);
const body = {
first_name : firstName
};
this.http.post("http://localhost:9001/user/findOne", body, { params: params })
.subscribe((resultData: any)=>
{
console.log(resultData);
});
}
Btw: Why don't you use GET instead of POST?

Error: Reference.set failed: First argument contains undefined in property

I'm trying to test a POST method in a Nodejs/express application. I've connected to the firebase database.
My question is mainly related to the error. What am I doing wrong and how can I fix this please?
This is the error report:
PS C:\Users\WorkoutApp_v1> node app.js
Server started on port: 3000
Error: Reference.set failed: First argument contains undefined in property 'workouts.-Lqkqtcf6e2RED2F_1av.name'
This is the workout.js file with POST method.
const express = require('express');
const router = express.Router();
const firebase = require('firebase');
router.get('/add', function(req,res,next) {
res.render('workouts/add');
});
router.post('/add', function(req,res,next) {
var workout = {
name: req.body.name,
discription: req.body.discription,
set: req.body.set,
repsTime: req.body.repsTime
}
// console.log(workout);
// return;
// const fbRef = firebase.database().ref();
// var dbRef = fbRef.child('workouts');
// dbRef.push().set(workout);
// alternative implementation of the above 3-lines
firebase.database().ref().child('workouts').push().set(workout);
req.flash('success_msg', 'Workout saved');
res.redirect('/workouts');
});
module.exports = router;
This is the add.ejs file.
<form method="post" action="/workouts/add">
<div class="form-group">
<label>Exercise</label>
<input type="text" class="form-control" name="name" placeholder="Workout Name">
<label>Description</label>
<input type="text" class="form-control" name="description" placeholder="Description">
<label>Set</label>
<input type="text" class="form-control" name="sets" placeholder="Number of sets">
<label>RepsTime</label>
<input type="text" class="form-control" name="repsTime" placeholder="Number of repsTime">
</div>
<button type="submit" class="btn btn-default">Submit</button>
<a class="btn btn-danger" href="/workouts">Close</a>
</form>
The value undefined can't be written in RTDB.
The value undefined is what you get when you access object properties that don't exist.
Your req.body.name is undefined because req.body doesn't have a name property.
What does your commented-out console.log(workout) print?
When you write code that might lead to writing undefined in RTDB, you should replace it with something else. In this scenario, you could use req.body.name || '', to replace a missing name property with an empty string.
In general, using || can cause trouble, because values like 0 and '' are equivalent to false, so they would be replaced by your default value.
A safer thing to do is value === undefined ? defaultValue : value.

returning or looking up object from html input in node express

I have an html/handlebars form set up with a Node/Express backend. the form offers options populated from a database. I am able to get the form to return a single user selected value and save it to my mongodb, but I really need the whole object.
{{#each proxyObj}}
<p>
<label>
<input type="radio" name="proxyTitle" value="{{title}}"/>
<span>{{title}}</span>
</label>
</p>
{{/each}}
and this is the express:
router.post("/proxies/:id", ensureAuthenticated, (req, res) => {
Project.findOne({
_id: req.params.id
}).then(project => {
const newProxy = {
proxyTitle: req.body.proxyTitle
// I need the other object values to go here, or to be able to retrieve them later
};
// Add to proxy array on the Project object in the collection
project.proxies.push(newProxy);
project.save().then(project => {
res.redirect(`/projects/stakeholders/${project.id}`);
});
});
});
Is it more sensible to try to load in the entire object as a value in the input field, or to return the id of the object, and look it up in the db? I need to display some of the returned object information on the same page, and also to use it later. Which is more efficient, and what is the best way to achieve it?
If I'm getting it right, the problem is that you're trying to put multiple inputs with the same name on one form in <input type="radio" name="proxyTitle" value="{{title}}"/>, which gives you something like
<input type="radio" name="proxyTitle" value="Title 1"/>
<input type="radio" name="proxyTitle" value="Title 2"/>
<input type="radio" name="proxyTitle" value="Title 3"/>
As explained here, the browsers will chew it, but the server-side handling may require some adjustments.
In your case, the easiest fix would be to add index to the names of parameters. So, your form would be looking like this:
{{#each proxyObj}}
<p>
<label>
<input type="radio" name="proxies[{{#key}}]" value="{{this}}"/>
<span>{{this}}</span>
</label>
</p>
{{/each}}
(note that if proxyObj is an array, you would have to use #index instead of #key; also, depending on the proxyObj fields' structure, you may have to use this.title as the values to display and whatnot).
As for your server-side handling, you'll have to loop through the proxies you receive and handle them one by one, e.g.
router.post("/proxies/:id", ensureAuthenticated, (req, res) => {
Project.findOne({
_id: req.params.id
}).then(project => {
project.proxies = []; // this is only in case you wanna remove the old ones first
const proxies = req.body.proxies;
for(let i = 0; i < proxies.length; i++) {
// Add to proxy array on the Project object in the collection
project.proxies.push({ proxyTitle: proxies[i].title });
}
project.save().then(project => {
res.redirect(`/projects/stakeholders/${project.id}`);
});
});
});

Angular 2 Populate select drop down values from Mongoose DB

I need to fetch the select drop down list vales from Mongo DB mongoose.
In my angular 2 i have something which is static as:
UPDATED CODE:
I want to achieve something like this and I have tried like :
<form role="form">
<fieldset class="form-group">
<label>Select Category</label><br/><br/>
<select [(ngModel)]="selectedObject" name="first" class="form-control">
//Static data
<!--<option>Select</option>
<option>Juices</option>
<option>Chats</option>
<option>Meals</option>-->
<option *ngFor="let c of categories"
[value]="c"
[selected]="c.categoryName == selectedObject.categoryName"
>
{{c.categoryName}}
</option>
</select>
</fieldset>
</form>
In my component.ts i have something like:
export class BlankPageComponent implements OnInit {
selectedObject = null;
categories = [];
constructor(private addproductService: AddproductService,
private flashMessage: FlashMessagesService,
private router: Router) { }
ngOnInit() {
const categories = {
category_name: this.category_name
}
this.addproductService.loadData(categories).subscribe(data => {
});
\src\app\shared\services\addproduct.service.ts
export class AddproductService {
categories: any;
loadData(pList: any) {
this.categories = pList;
if (this.categories.length > 0) {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
return this.http.post('http://10.22.*.*:3000/categories/get', this.categories, { headers: headers })
.map(res => res.json());
//this.selectedObject = this.categories[0];
}
}
Error as of now: TypeError: Cannot read property 'subscribe' of undefined
But i need to get the values of the drop down from backend(bind them)
In my mongoose backend i have a document with field name : category_name which has values like : Juice, Meals, Chats etc and in postman i fetch them like using API:
http://10.22..:3000/categories/get
I am able to fetch the category from nodejs using GET request,
But how to bind the select control and populate data from mongoose
.ts
categories = ['Juices', 'Chats', 'Meals'];
selectedCategory: string;
.html
<form role="form">
<fieldset class="form-group">
<label>Select Category</label><br/><br/>
<select [(ngModel)]="selectedCategory" class="form-control">
<option disabled>--Select--</option>
<option *ngFor="let category of categories" [value]="category">{{category}}</option>
</select>
</fieldset>
</form>

How to catch the object_id of a post submit in Node.js (MongoJS)?

I have this code in app.js where I insert the content of the title and content fields to their respective document fields in MongoDB:
//post to 'post/new'..
app.post('/post/new', function(req, res){
//get the `title` and `content` fields & save them as variables to be later reused (they rely on the `name:` values).
var title = req.body.title;
var content = req.body.content;
//call the database and find the `_id` to be used in the redirect later..
db.local.find({_id: ObjectId(req.params.id)}, function(id) {});
//insert the title and content in the database (taken from the submit form)
db.local.insert ( {title: title, content: content},
//not sure if I really need to define an err&doc right now so to be ignored..
function(err, doc) {
//redirect to "localhost.com/post/(post)_id/(post)title"
res.redirect('/post/'+req.params.id+'/'+req.body.title);
});
});
This is what I have on post_new.ejs:
<form method="post">
<div>
<div>
<span>Title :</span>
<input type="text" name="title" id="editPostTitle" />
</div>
<div>
<span>Content :</span>
<textarea name="content" rows="20" id="editPostBody"></textarea>
</div>
<div id='editPostSubmit'>
<input type="submit" value="Send" />
</div>
</div>
</form>
The problem is that I get all but no _id in the res.redirect to work, meaning, the title works wonderfully, but the _id no..
How can I get the object id to work in the redirect? Thank you!
EDIT
This is the problem I get and think it's unrelated..but I'll include it for the full view of the issue.
500 Error: Argument passed in must be a single String of 12 bytes or a string of 24 hex characters
Assuming you are using the native node MongoDB driver the callback of the insert function returns the array of inserted objects.
The example in those docs is a pretty good one. Adjusted for your example, it would like something like this:
var MongoClient = require('mongodb').MongoClient;
MongoClient.connect('mongodb://127.0.0.1:27017/test', function(err, db) {
db.collection('local').insert({title: title, content: content}, function(err, docs) {
console.log('Inserted _id is '+docs[0]._id);
});
});
Regarding your error, it sounds like req.params.id is not a valid BSON ObjectId.

Resources