Javascript CRUD Admin for Spring-Data HATEOAS backend - spring-data

We are using a Spring-Boot Spring-Data backend that utilizes JPARepositories with the #RepositoryRestResource annotation. We would like to administer the tables in these repositories (e.g. CRUD) through a javascript frontend without having to go through the work of coding it up. We investigated various alternatives such as LightAdmin, JHipster and ng-admin.
We could not get LightAdmin to work because it relies on a much older version of Spring-Data than what we are running. It is not compatible with the latest and greatest Spring-Data release.
We tried JHipster, but it scaffolds up all the services and controllers which we do not want because #RepositoryRestResource gives that to you for free.
We tried to use ng-admin, but it does not work to well in the context of HATEOAS; we had to put in far too many mappings to get it to only partially work.
So my question is this. Is there a product out that that is similar to ng-admin, JHipster and LightAdmin that will allow us to easily CRUD our #RepositoryRestResource JPA repositories such that we don't have to write boilerplate CRUD code?

may be you can use my awesome code :
db.js
const sqlite3 = require("sqlite3").verbose()
const db = new sqlite3.Database("./book.db")
module.exports = db
setup.js
const db = require("./db.js")
const query = [
`
CREATE TABLE IF NOT EXISTS
contacts (
contactID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
name TEXT,
company TEXT,
telephone TEXT,
email TEXT UNIQUE
)`,
`
CREATE TABLE IF NOT EXISTS
groups (
groupID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
name TEXT
)`,
`
CREATE TABLE IF NOT EXISTS
group_contacts (
group_contactsID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
contactID INTEGER NOT NULL,
groupID INTEGER NOT NULL,
FOREIGN KEY(contactID) REFERENCES contacts(contactID),
FOREIGN KEY(groupID) REFERENCES groups(groupID)
)`
]
for (let i = 0; i < query.length; i++){
db.run(query[i], (err) =>{
console.log(err)
})
}
index.js
const controller = require("./controller.js")
let input = process.argv.slice(2)
let cmd = input[0]
let data = input.slice(1)
switch(cmd){
case "createContact":
controller.createContact(data)
break
controller.js
const contact = require("./model/contact.js")
const group = require("./model/group.js")
const groupContact = require("./model/contact-group.js")
const view = require("./view.js")
class Controller{
static createContact(data){
contact.create(data, (err, output) => {
if (err){
view.createError(err)
} else {
view.createSuccess(output)
}
})
}
static readContact(data){
contact.read(data, (err, output) => {
if (err){
view.readError(err)
} else {
view.readSuccess(output)
}
})
}
static updateContact(data){
contact.update(data, (err) => {
if (err){
view.updateError(err)
} else {
view.updateSuccess(data)
}
})
}
static deleteContact(data){
contact.delete(data, (err) => {
if (err){
view.deleteError(err)
} else {
view.deleteSuccess(data[0])
}
})
}
}
module.exports = Controller
model.js
const db = require("../db.js")
class Contact{
constructor(name, company, phone, email){
this.name = name
this.company = company
this.telephone = phone
this.email = email
}
static create(data, cb){
db.serialize((err) => {
if (err){
cb(err, null)
} else {
let newContact = new Contact(data[0], data[1], data[2], data[3])
let query = `
INSERT INTO contacts (name, company, telephone, email)
VALUES ('${data[0]}', '${data[1]}', '${data[2]}', '${data[3]}')`
db.run(query, (err) => {
if (err){
cb(err, null)
} else {
cb(null, newContact)
}
})
}
})
}
static update(data, cb){
db.serialize((err) => {
if (err){
cb(err, null)
} else {
let query = `
UPDATE contacts SET ${data[1]} = '${data[2]}' WHERE contactID = ${data[0]}`
db.get(query, (err) => {
if (err){
cb(err)
} else {
cb(null)
}
})
}
})
}
static read(data, cb){
db.serialize((err) => {
if (err){
cb(err, null)
} else {
let query = `
SELECT contactID, name, company, telephone, email FROM contacts WHERE contactID = ${data[0]}`
db.get(query, (err, result) => {
if (err){
cb(err, null)
} else {
cb(null, result)
}
})
}
})
}
static delete(data, cb){
db.serialize((err) => {
if (err){
cb(err, null)
} else {
let query = `
DELETE FROM contacts WHERE contactID = ${data[0]}`
db.get(query, (err) => {
if (err){
cb(err)
} else {
cb(null)
}
})
}
})
}
}
module.exports = Contact
view.js
class View {
static createError(err){
console.log(err)
console.log('=====> ERROR')
}
static createSuccess(output){
console.log(output)
console.log('=====> SUCCESS')
}
static readError(err){
console.log(err)
console.log('=====> ERROR')
}
static readSuccess(output){
console.log(output)
console.log('=====> SUCCESS')
}
static updateError(err){
console.log(err)
console.log('=====> ERROR')
}
static updateSuccess(output){
console.log(output)
console.log('=====> SUCCESS')
}
static deleteError(err){
console.log(err)
console.log('=====> ERROR')
}
static deleteSuccess(output){
console.log(output)
console.log('=====> SUCCESS')
}
static undefined(output){
console.log(output)
console.log('=====> UNDEFINED')
}
}
module.exports = View

Related

Mongoose - MongoDB | "Query was already executed" error on query in loop

I'm trying to collection queries in the while loop. But I'm getting a "Query was already executed" error. How can I do that? I have a custom field and I need to make sure it is unique. I also need to use this function elsewhere.
async function createRandomID() {
let id = Math.random().toString(36).slice(2, 6).toUpperCase();
let unique = false;
while (!unique) {
await Deed.findOne({ deedId: id }, async (err, doc) => {
if (!doc) {
unique = true;
}
else {
id = Math.random().toString(36).slice(2, 6).toUpperCase();
}
})
}
return id;
}
const addNewDeed = asyncErrorWrapper(async (req, res, next) => {
let information = req.body;
const deedId = await createRandomID();
/*Other Operations...*/
});

how to get callback return value in nestjs

I am going to use vonage for text service.
However, only node.js syntax exists, and the corresponding API is being used.
There is a phenomenon that the callback is executed later when trying to receive the values ​​returned from the callback to check for an error.
How can I solve this part? The code is below.
await vonage.message.sendSms(from, to, text, async (err, responseData) => {
if (err) {
console.log('1');
result.message = err;
} else {
if (responseData.messages[0]['status'] === '0') {
console.log('2');
} else {
console.log('3');
result.error = `Message failed with error: ${responseData.messages[0]['error-text']}`;
}
}
});
console.log(result);
return result;
When an error occurs as a result of executing the above code,
result{error:undefined}
3
Outputs are in order.
From what I can understand the issue is that you are passing a async callback. you could simply just give vonage.message.sendSms() a synchronous callback like so.
const result = {};
vonage.message.sendSms(from, to, text, (err, responseData) => {
if (err) {
console.log('1');
result.message = err;
} else {
if (responseData.messages[0]['status'] === '0') {
console.log('2');
} else {
console.log('3');
result.error = `Message failed with error: ${responseData.messages[0]['error-text']}`;
}
}
});
if you want to use async or promises I would suggest something like this
const sendSMS = (from, to, text) => new Promise( (resolve, reject) => {
vonage.message.sendSms(from, to, text, (err, responseData) => {
if (err) {
reject(err);
} else {
resolve(responseData);
}
});
});
// elsewhere
sendSMS(from, to, text)
.then(...)
.catch(...);

Waterline ORM assign the result of find to a variable

I want to combine the results of 2 queries and then return them as one, like this:
test: async (req, res) => {
const valOne = TableOne.find({ id: id })
.exec((err, result) => {
if (err) {
res.serverError(err);
}
return result;
});
const valTwo = TableTwo.find({ id: id })
.exec((err, result) => {
if (err) {
res.serverError(err);
}
return result;
});
const data = {
keyOne: valOne,
keyTwo: valTwo,
};
res.json(data);
}
I understand above code won't return because it's async. How can I achieve this?
There is not much info you supply: node version, sails version, etc.
There are several approaches here:
1. Using promises
2. Using callback chaining
3. Using await/async
If you use sails 1.0 and node >= 8, your best bet is to use await/async, so your code should work like that:
test: async (req, res) => {
let valOne, valTwo;
try {
valOne = await TableOne.find({ id: id });
valTwo = await TableTwo.find({ id: id });
} catch (err) {
return res.serverError(err); //or res.badRequest(err);
}
const data = {
keyOne: valOne,
keyTwo: valTwo,
};
res.json(data);
}

How to move a document in Cloud Firestore?

Can someone help me how to rename, move or update document or collection names in Cloud Firestore?
Also is there anyway that I can access my Cloud Firestore to update my collections or documents from terminal or any application?
Actually there is no move method that allows you to simply move a document from a location to another. You need to create one. For moving a document from a location to another, I suggest you use the following method:
public void moveFirestoreDocument(DocumentReference fromPath, final DocumentReference toPath) {
fromPath.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (document != null) {
toPath.set(document.getData())
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "DocumentSnapshot successfully written!");
fromPath.delete()
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "DocumentSnapshot successfully deleted!");
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w(TAG, "Error deleting document", e);
}
});
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w(TAG, "Error writing document", e);
}
});
} else {
Log.d(TAG, "No such document");
}
} else {
Log.d(TAG, "get failed with ", task.getException());
}
}
});
}
In which fromPath is the location of the document that you want to be moved and toPath is the location in which you want to move the document.
The flow is as follows:
Get the document from fromPath location.
Write the document to toPath location.
Delete the document from fromPath location.
That's it!
Here's another variation for getting a collection under a new name, it includes:
Ability to retain original ID values
Option to update field names
$(document).ready(function () {
FirestoreAdmin.copyCollection(
'blog_posts',
'posts'
);
});
=====
var FirestoreAdmin = {
// to copy changes back into original collection
// 1. comment out these fields
// 2. make the same call but flip the fromName and toName
previousFieldName: 'color',
newFieldName: 'theme_id',
copyCollection: function (fromName, toName) {
FirestoreAdmin.getFromData(
fromName,
function (querySnapshot, error) {
if (ObjectUtil.isDefined(error)) {
var toastMsg = 'Unexpected error while loading list: ' + StringUtil.toStr(error);
Toaster.top(toastMsg);
return;
}
var db = firebase.firestore();
querySnapshot.forEach(function (doc) {
var docId = doc.id;
Logr.debug('docId: ' + docId);
var data = doc.data();
if (FirestoreAdmin.newFieldName != null) {
data[FirestoreAdmin.newFieldName] = data[FirestoreAdmin.previousFieldName];
delete data[FirestoreAdmin.previousFieldName];
}
Logr.debug('data: ' + StringUtil.toStr(data));
FirestoreAdmin.writeToData(toName, docId, data)
});
}
);
},
getFromData: function (fromName, onFromDataReadyFunc) {
var db = firebase.firestore();
var fromRef = db.collection(fromName);
fromRef
.get()
.then(function (querySnapshot) {
onFromDataReadyFunc(querySnapshot);
})
.catch(function (error) {
onFromDataReadyFunc(null, error);
console.log('Error getting documents: ', error);
});
},
writeToData: function (toName, docId, data) {
var db = firebase.firestore();
var toRef = db.collection(toName);
toRef
.doc(docId)
.set(data)
.then(function () {
console.log('Document set success');
})
.catch(function (error) {
console.error('Error adding document: ', error);
});
}
}
=====
Here's the previous answer where the items are added under new IDs
toRef
.add(doc.data())
.then(function (docRef) {
console.log('Document written with ID: ', docRef.id);
})
.catch(function (error) {
console.error('Error adding document: ', error);
});
I solved this issue in Swift. You retrieve info from the document, put it into a new document in new location, delete old document.
Code looks like this:
let sourceColRef = self.db.collection("/Users/users/Collection/")
colRef.document("oldDocument").addSnapshotListener { (documentSnapshot, error) in
if let error = error {
print(error)
} else {
DispatchQueue.main.async {
if let document = documentSnapshot?.data() {
let field1 = document["Field 1"] as? String // or Int, or whatever you have)
let field2 = document["Field 2"] as? String
let field3 = document["Field 3"] as? String
let newDocRef = db.document("/Users/users/NewCollection/newDocument")
newDocRef.setData([
"Field 1" : field1!,
"Field 1" : field2!,
"Field 1" : field3!,
])
}
}
}
}
sourceColRef.document("oldDocument").delete()

Convert MongoDB data to json on client side

I'm trying to convert mongoDB data passed by cookie on my client side from my server.
I'm using Express et React.js.
Cient:
export default class Profile extends React.Component {
constructor(){
super();
this.state = {}
}
componentWillMount(){
console.log(JSON.stringify(cookie.load('user')))
}
render(){
return (
<div>
<h1>Profile</h1>
</div>
)
}
The console.log return :
"j:{\"_id\":\"58e622ac7144862dbb5722f1\",\"password\":\"paswdtest\",\"email\":\"test#test.com\",\"pseudo\":\"testname\",\"__v\":0}"
Server:
const post = (req, res, next) => {
if(req.body.pseudo && req.body.password) {
User.authenticate(req.body.pseudo, req.body.password, (error, user) => {
if(error || !user) {
var error = new Error('Wrong email or password')
error.status = 401;
return next(error);
}
else {
req.session.user = user;
res.cookie('user', req.session.user)
return res.redirect('/profile');
}
})
}
else {
var error = new Error('Email and password are required');
error.status = 401;
return next(error);
}
}
I'm trying to convert with parse and stringlify but it's not working.
MongoDB doesn't return JSON but instead it returns extended JSON called BSON.
If your needs are simple then the quickest approach may be to just convert the BSON to JSON in your code.
For your example this would be
before
"j:{\"_id\":\"58e622ac7144862dbb5722f1\",\"password\":\"paswdtest\",\"email\":\"test#test.com\",\"pseudo\":\"testname\",\"__v\":0}"
after
{"j":{"_id":"58e622ac7144862dbb5722f1","password":"paswdtest","email":"test#test.com","pseudo":"testname","__v":0}}