node pagination in json array - node.js

I have implemented the following code for pagination but I am unable to make it work. I need to complete it with the following json data:
following code is for Vt.js file
const express = require('express');
const app = express();
const cors = require('cors');
var MongoClient = require('mongodb').MongoClient;
app.use(cors())
var url = "mongodb://localhost:27017/";
var pagination = require('pagination');
var paginator = pagination.create('search', {
prelink: '/users',
current: 2,
rowsPerPage: 2,
totalResult: 10020
});
console.log(paginator.render());
app.get('/users', function(req, res) {
MongoClient.connect(url, function(err, db) {
if (err)
throw err;
var dbo = db.db("MyNewDatabase");
var data = dbo.collection("VirtualCapitalDB").find({}).toArray(function(err, result) {
if (err)
throw err;
console.log(result);
res.json(result);
db.close();
});
});
})
app.listen(8080, ()=>console.log('Listening on port 8080'));
once you access it without pagination you can get following json array
[{
"_id": "5bcb3c77dc56e939187c13a5",
"firstname": "dumindu",
"lastname": "nagasinghe",
"videocount": 5
}, {
"_id": "5bcb3ce6dc56e939187c13a9",
"firstname": "cha",
"lastname": "advv",
"videocount": 10
}, {
"_id": "5bcb3d4bdc56e939187c13ab",
"firstname": "dvvs",
"lastname": "scvssv",
"videocount": 4
}, {
"_id": "5bcb3d7adc56e939187c13ac",
"firstname": "advav",
"lastname": "dvdvv",
"videocount": 5
}, {
"_id": "5bcb40f7a768f83918480a2b",
"firstname": "advav",
"lastname": "dvdvv",
"videocount": 5
}, {
"_id": "5bcb4103a768f83918480a2c",
"firstname": "advav",
"lastname": "dvdvv",
"videocount": 5
}, {
"_id": "5bcb4106a768f83918480a2d",
"firstname": "advav",
"lastname": "dvdvv",
"videocount": 5
}, {
"_id": "5bcb4125a768f83918480a2e",
"firstname": "advav",
"lastname": "dvdvv",
"videocount": 5
}]
But I need to add pagination and get the 2 data objects for single page. How to implement that in code?

Best way to write pagination of array items
paginator(items, page, per_page) {
var page = page || 1,
per_page = per_page || 10,
offset = (page - 1) * per_page,
paginatedItems = items.slice(offset).slice(0, per_page),
total_pages = Math.ceil(items.length / per_page);
return {
page: page,
per_page: per_page,
pre_page: page - 1 ? page - 1 : null,
next_page: (total_pages > page) ? page + 1 : null,
total: items.length,
total_pages: total_pages,
data: paginatedItems
};
}

Try this module.
// Fetch all running lent loans
module.exports.fetchLends = function (req, res, next) {
var perPage = 5;
var page = req.body.page || 1; // req.body.page pass from client, which page required.
loans
.find({
lenderId: req.user._id,
_disbursed: true,
_approved: true,
_completed: false
})
.select(
"lenderId _disbursed _approved _completed userId disbursed_timestamp status principal lender_interest_amount emi_type completed_timestamp disbursed_timestamp emi.lender_interest_amount emi._disbursed emi._completed emi.principal emi.lender_interest_amount emi.status emi.due_date emi.extension_date_1 emi.extension_date_2 emi.extension_date_3"
)
.populate({
path: "userId",
select: "name"
})
.skip(perPage * page - perPage)
.limit(perPage)
.sort({
disbursed_timestamp: -1
})
.exec(function (err, loan) {
console.log(loan)
)}
}

You want to use the express-paginate module, it's better suited for this case. See the documentation on their github page.
The pagination module you are using needs to create a new http request to get the data, it's not what you need for your application.

Related

Mongodb Schema issue

Here i am using Nodejs application to get JSON response from external API.I need to capture few key-value pair of this response and need to save it MongoDB.
I am getting the response properly, but i am unable to save the data in database.
Requirement:
Each time i get this response from External server , i need to save it in table by rewriting any documents if already exists in this collection. Here i have nearly 7 array items in json response , i need to save corresponding key value pair from all of the items automatically .
Model:
var mongoose = require('mongoose');
const getAllUsersDataSchema = new mongoose.Schema({
userRefID:[] ,
userName:[],
divisionId: [{}],
divisionName:[{}],
emailId :[{}],
})
module.exports = getAllUsers = mongoose.model('getAllUsers',getAllUsersDataSchema );
**API Call where i am capturing external API response:**
const express = require('express');
const router = express.Router();
const request = require('request');
const config = require('../config');
const fs = require('fs');
const getAllUsers = require ('../db/getAllUsersListmodel');
var mongoose = require('mongoose');
mongoose.connect ('mongodb://localhost/testdb',{ useUnifiedTopology: true , useNewUrlParser: true });
router.get('/', (req, res) => {
// token in session -> get user data and send it back to the Angular app
var data =fs.readFileSync('../teamlist.txt', {encoding:'utf8'} )
console.log(data);
if (data) {
request(
{
method: 'GET',
url: 'https://api.mypurecloud.com/api/v2/users',
headers: {
'Authorization': 'Bearer ' + data
}
},
// callback
(error, response, body) => {
let userInfoResponse = JSON.parse(body);
res.send(userInfoResponse);
console.log(userInfoResponse.entities.length)
console.log(userInfoResponse.entities[0].division.id)
getAllUsers.create({
userRefID : userInfoResponse.entities.id,
userName: userInfoResponse.entities.name,
divisionId: userInfoResponse.entities.division.id,
divisionName:userInfoResponse.entities.division.name,
emailId:userInfoResponse.entities.primaryContactInfo.address
}, (error,post)=>{
console.log(error,post);
});
}
);
}
// no token -> send nothing
else {
res.send("Token Not Present - Kindly login in back");
}
//console.log(req.session.token);
});
Data is saving in DB but not getting any array data saved in to it.
{
"_id" : ObjectId("5fd998d61439a434983702cd"),
"userRefID" : [ ],
"userName" : [ ],
"__v" : 0
}
This is exact API JSON response i am trying to save it in DB and use it for future references:
{
"entities": [
{
"id": "07f426ff-506f-4e5e-afdb-2c7397edac61",
"name": "EPS Purecloud Support",
"division": {
"id": "36852a81-ad7f-4c71-a1cd-7f431c05179f",
"name": "",
"selfUri": "/api/v2/authorization/divisions/36852a81-ad7f-4c71-a1cd-7f431c05179f"
},
"chat": {
"jabberId": "5dcc25e1db8c7e19238a287d#cognizant3.orgspan.com"
},
"email": "eps#genesys.com",
"primaryContactInfo": [
{
"address": "eps#genesys.com",
"mediaType": "EMAIL",
"type": "PRIMARY"
}
],
"addresses": [],
"state": "active",
"username": "eps#genesys.com",
"version": 3,
"acdAutoAnswer": false,
"selfUri": "/api/v2/users/07f426ff-506f-4e5e-afdb-2c7397edac61"
},
{
"id": "c5ce06dc-6265-4d16-be18-f5fc5a918295",
"name": "Generic",
"division": {
"id": "36852a81-ad7f-4c71-a1cd-7f431c05179f",
"name": "",
"selfUri": "/api/v2/authorization/divisions/36852a81-ad7f-4c71-a1cd-7f431c05179f"
},
"chat": {
"jabberId": "5ebab3dba6686314f6913b98#cognizant3.orgspan.com"
},
"email": "integration-generic-a03293c0-945d-11ea-a64c-ebeb45b9d295#webhook.com",
"primaryContactInfo": [
{
"address": "integration-generic-a03293c0-945d-11ea-a64c-ebeb45b9d295#webhook.com",
"mediaType": "EMAIL",
"type": "PRIMARY"
}
],
"addresses": [],
"state": "active",
"username": "integration-generic-a03293c0-945d-11ea-a64c-ebeb45b9d295#webhook.com",
"version": 2,
"acdAutoAnswer": false,
"selfUri": "/api/v2/users/c5ce06dc-6265-4d16-be18-f5fc5a918295"
},
{
/** 3rd User *********/
}
{
/** 4th User *********/
}
],
"pageSize": 25,
"pageNumber": 1,
"total": 7,
"firstUri": "/api/v2/users?pageSize=25&pageNumber=1",
"selfUri": "/api/v2/users?pageSize=25&pageNumber=1",
"lastUri": "/api/v2/users?pageSize=25&pageNumber=1",
"pageCount": 1
}
Entities is an array of objects, but you are trying to refer to its properties as an object:
userRefID : userInfoResponse.entities.id, // but "entities": [ {"id":"...", "name":"..."} ],
userName: userInfoResponse.entities.name,
You have to collect the data in a loop, and only then insert it into the database:
const usersArray = userInfoResponse.entities.map(el => ({
userRefID : el.id,
userName: el.name,
divisionId: el.division.id,
divisionName: el.division.name,
emailId: el.primaryContactInfo[0].address
}));
getAllUsers.insertMany(usersArray)

How to post and populate bill

I've got a relational json called "client" inside Bill's model. This is my code:
const mongoose = require("mongoose");
const { Schema } = mongoose;
const billSchema = new Schema({
number: Number,
date: { type: Date, default: Date.now() },
type: String,
local: String,
client: { type: mongoose.Schema.Types.ObjectId, ref: "clients", required: true },
detail: [
{
quantity: Number,
product: { code: Number, name: String, price: Number },
undertotal: Number
}
],
total: Number
});
mongoose.model("bills", billSchema);
this is my post route:
app.post("/api/bills", async (req, res) => {
const { number, type, local, client, detail, total } = req.body;
await Client.findById(req.body.client._id).then(client => {
if (!client) {
return res.status(404).json({
message: "client not found"
});
}
});
const bill = new Bill({
number,
date: new Date(),
type,
local,
client,
detail,
total
});
try {
let newBill = await bill.save();
res.status(201).send(newBill);
} catch (err) {
if (err.name === "MongoError") {
res.status(409).send(err.message);
}
res.status(500).send(err);
}
});
//my get route
app.get("/api/bills", function(req, res) {
Bill.find({}, function(err, bills) {
Client.populate(bills, { path: "clients" }, function(err, bills) {
res.status(200).send(bills);
});
});
});
I want something like this:
{
"number": 302,
"type": "c",
"local": "porstmouth",
"client": {
"address": {
"street": "victoria street",
"number": 1001,
"floor": "2",
"flat": 4
},
"_id": "5dab929613fb682b48e4ca6b",
"name": "luke skywalker",
"mail": "l.skywalker#yahoo.com",
"cuil": "39193219",
"phone": 128391,
"__v": 0
},
"detail": [
{
"quantity": 500,
"product": {
"code": 300,
"name": "P2",
"price": 800
},
"undertotal": 5000
}
],
"total": 11000
}
But I see this result:
{
"date": "2019-10-20T12:27:17.162Z",
"_id": "5dac52a577e09b4acc45718d",
"number": 302,
"type": "c",
"local": "porstmouth ",
"client": "5dab929613fb682b48e4ca6b",
"detail": [
{
"_id": "5dac52a577e09b4acc45718e",
"quantity": 500,
"product": {
"code": 300,
"name": "P2",
"price": 800
},
"undertotal": 5000
}
],
"total": 11000,
"__v": 0
}
I don't want to see id client only. I want to see all content from client inside bill.
I tried to do with populate method, but I haven't results.
So, Which is form to post and populate a nested json relational object in this case?
While posting only clientId is enough.
So your post route can be like this (you both used await and then, which is incorrect, so I refactored it to use only await)
app.post('/api/bills', async (req, res) => {
const { number, type, local, client, detail, total } = req.body;
let existingClient = await Client.findById(req.body.client._id)
if (!existingClient) {
return res.status(404).json({
message: "client not found"
});
}
const bill = new Bill({
number,
date: new Date(),
type,
local,
client: req.body.client._id
detail,
total
})
try {
let newBill = await bill.save();
res.status(201).send(newBill);
} catch (err) {
if (err.name === 'MongoError') {
res.status(409).send(err.message);
}
res.status(500).send(err);
}
});
And in the get route to retrieve all the client info you need to populate it like this:
app.get('/api/bills', async (req, res) => {
try {
const bills = await Bill.find({}).populate("clients");
res.status(200).send(bills);
} catch (err) {
console.log(err);
res.status(500).send(err);
}
}
)

Node mongo count query items

I have a simple GET search. Problem is that when I use some criteria like status or name or email it shows correct results BUT pagination behave like there were no criteria.
For example, there is one user in DB with name John so I search for John and it gives me exactly him as a result. But pagination shows me 10pages and I don't know how to fix it. When I parse count it gives me all results not only one,
Here is my controller
/**
* GET /admin/users/:page
* Find users
*/
exports.findUsers = (req, res, next) => {
const perPage = 13
const page = Number(req.params.page) || 1
var query = {};
const possibleQueryProps = [{
"key": "id",
"queryKey": "_id"
},
{
"key": "email",
"queryKey": "email"
},
{
"key": "firstname",
"queryKey": "profile.firstname"
},
{
"key": "lastname",
"queryKey": "profile.lastname"
},
{
"key": "location",
"queryKey": "profile.location"
},
{
"key": "status",
"queryKey": "profile.status"
}
];
possibleQueryProps.forEach(prop => {
if (req.query[prop.key]) {
query[prop.queryKey] = req.query[prop.key];
}
});
console.log(query)
User
.find(query)
.skip((perPage * page) - perPage)
.limit(perPage)
.exec(function (err, users) {
User.countDocuments().exec(function (err, count) {
if (err) return next(err)
res.render('admin/users', {
layout: "admin",
users: users,
query: req.query,
active: {
users: true
},
current: page,
pages: Math.ceil(count / perPage),
helpers,
pagesArr: Array.from(Array(((Math.ceil(count / perPage)))).keys()).map(i => 1 + i),
pagination: core.pagination(page, (Math.ceil(count / perPage))),
})
})
})
};
I will be thankful for any advice.
But pagination shows me 10pages and I don't know how to fix it. When I parse count it gives me all results not only one,
You need to count only documents that match your search criteria, so rather than User.countDocuments() you'll want something like User.countDocuments(query).

Finding a subdoc by id with Mongoose

I am trying to find and update a subdoc using mongoose and mongdb but I can't seem to find the subdocs using the ids.
My schema
var Attending = new Schema({
users: []
});
var Query = new Schema({
name: [],
url: [],
attending: [Attending],
img: []
});
Using the ids for both docs, just finding returns null for the doc. However, if i only using the general Id I can find the entire doc but not the subdoc.
Queries.findOne(
{ "_id": queryId, "attending._id": attendingId },
function(err, doc) {
if (err) throw err;
console.log(doc);
res.render('index');
}
);
sample doc
{
"_id": {
"$oid": "58d995026d7c8f0a3028a50f"
},
"img": [
"https://pic1",
"https://pic2"
],
"attending": [
{
"_id": {
"$oid": "58d995026d7c8f0a3028a505"
},
"users": [
"somebody"
]
},
{
"_id": {
"$oid": "58d995026d7c8f0a3028a506"
},
"users": [
"another person"
]
}
],
"url": [
"https://www.yelp.com/2",
"https://www.yelp.com/1"
],
"name": [
"The Rivermill",
"Sharkeys"
],
"__v": 0
}
I am using the correct ids and expect to the first subdoc in attending to be returned or whichever one is searched. Instead null is returned.
Queries is made like this:
var names = [];
var urls = [];
var imgUrls = [];
var attendingArray = [];
for (var i=0; i<10; i++) {
names.push(businesses[i].name);
urls.push(businesses[i].url);
imgUrls.push(businesses[i].image_url);
//add attending schema
var newAttending = Attending({
users: ["somebody"]
});
attendingArray.push(newAttending);
}
var newQuery = Queries({
name: names,
url: urls,
attending: attendingArray,
img: imgUrls
});

update parent child data nodejs mongodb

I am new in mongodb with nodejs.I want to update the comments data.Here is my document
{
"__v": NumberInt(0),
"_id": ObjectId("565443b1172e19d51f98b0ed"),
"address": "tohana",
"comments": [
{
"_id": ObjectId("5654455fe088d89c20736e3c"),
"comment": "good man",
"uemail": "dinesh#gmail.com",
"uname": "dinesh"
},
{
"_id": ObjectId("565445e471dce6ca20705a84"),
"comment": "nice person",
"uemail": "kr#gmail.com",
"uname": "krishan"
},
{
"_id": ObjectId("5654460e7aa73bec2064060e"),
"comment": "bad person",
"uemail": "Rai",
"uname": "Rahul"
}
],
"email": "nishantg#ocodewire.com"▼,
"name": "Nishant"
}
I am using Angular js in frontend and nodeJs as backend. Here is my code:
app.post('/commentsSave/:id', function(req, res) {
var id = req.params.id; // userId
var input = JSON.parse(JSON.stringify(req.body)); //commentData
var commentId = input.id; //commentId
var name = input.name;
var email = input.email;
var comment = input.comment
res.send({data:id,data2:input});
})
app.post('/commentsSave/:id', function(req, res) {
var id = req.params.id; // userId
var input = JSON.parse(JSON.stringify(req.body)); //commentData
var commentId = input.id; //commentId
var name = input.name;
var email = input.email;
var comment = input.comment
Users.update({'comments._id': input.id},
{
$set: {
'comments.$.name': name,
'comments.$.email': email,
'comments.$.comment': comment
}
},function(error, result){
if(error){
console.log(error);
}
else{
console.log(result);
}
})
}

Resources