Breeze Error: A MergeStrategy of 'Disallowed' - node.js

I am getting this error when running the sample application for AngularJS from Breeze's website.
This is the code for the controller breezectl.js:
'use strict';
angular.module('mean').controller('breezeController', ['$scope', 'Global', 'dataservice',
function($scope, Global, dataservice) {
$scope.global = Global;
$scope.breeze = {
name: 'Breeze Sample'
};
//$scope.results = dataservice;
function getProducts() {
function success(data) {
$scope.results = data;
}
function failed(error) {
$scope.results = error.message;
}
dataservice.getAllProducts()
.then(success)
.catch(failed);
}
getProducts();
}
]);
dataservice.getAllProducts() enters the catch(failed) branch with this error message: "A MergeStrategy of 'Disallowed' does not allow you to attach an entity when an entity with the same key is already attached"
This is the code for dataservice.js:
'use strict';
angular.module('mean').factory('dataservice', ['breeze', 'entityManagerFactory',
function(breeze, entityManagerFactory) {
var manager = entityManagerFactory.newManager();
function getAllProducts(){
function success(data) {
return data.results;
}
return breeze.EntityQuery.from('Products')
.using(manager).execute()
.then(success);
}
var service = {
getAllProducts: getAllProducts
};
return service;
}
]);
Note: A direct call to Products from the Restful API (localhost:3000/breeze/northwind/Products) works properly and returns a set of Json objects representing all of the products in the collection.

Steve Schmitt are right. My metadata.json had the "defaultResourceName" property with a different name that the database collection.
I changed "Products" to "products" and this works.
Many thanks to all of you.

Related

Error: addReview is not a function in MERN application

I'm following along with a tutorial to create a movie review app on the MERN stack.
When calling my API using Insomnia, I'm getting the error "ReviewsDAO.addReview is not a function"
reviewsDAO.js:
import mongodb from "mongodb"
const ObjectId = mongodb.ObjectId
let reviews
export default class ReviewsDAO{
static async injectDB(conn){
if(reviews){
return
}
try { reviews = await conn.db(process.env.MOVIEREVIEWS_NS).collection('reviews')}
catch(e){
console.error(`unable to establish connection handle in reviewDAO: ${e}`)
}
}
static async addReview(movieId, user, review, date){
try{
const reviewDoc = {
name: user.name,
user_id: user._id,
date: date,
review: review,
movie_id: ObjectId(movieId)
}
return await reviews.insertOne(reviewDoc)
}
catch(e) {
console.error(`unable to post review ${e}`)
return {error: e}
}
}
reviews.controller.js:
import ReviewsDAO from '../dao/reviewsDAO.js'
export default class ReviewsController{
static async apiPostReview(req,res,next) {
const reviewsDAO = new ReviewsDAO()
try{
const movieId = req.body.movie_id
const review = req.body.review
const userInfo = {
name: req.body.name,
_id: req.body.user_id
}
const date = new Date()
const ReviewResponse = await reviewsDAO.addReview(
movieId,
userInfo,
review,
date
)
res.json({status: "success"})
}
catch(e) {
res.status(500).json({error: e.message})
}
}
The reviews collection is also not being created in MongoDB. But maybe that isn't supposed to happen until we create our first review.
Why isn't my function being called appropriately?
You need to instantiate a ReviewsDAO object in order to call its methods.
const reviewsDAO = new ReviewsDAO()
Then you will be able to access the addReview() method
You are calling the class method without initializing the object.
For example:
class Animal{
function sayhello(){
console.log("Hello")
}
}
// I can call the sayhello method by creating an object.
var dog=new Animal()
dog.sayhello() //prints "Hello"
But in your case, you are calling the method without creating the object.
Animal.sayhello()
// It will create an error
So initialise the object and call the method
const reviewsDAO = new ReviewsDAO()
reviewDAO.addreviews()
The static keyword defines static methods for classes.
Static methods are called directly on the class (Car from the example above) - without creating an instance/object (mycar) of the class
So
const Reviewsdao= new ReviewsDAO()
ReviewsDAO().addreviews()
Call the method with the class name after initialising it.

How to create manual mock with jest in nodejs app for mailgun-js?

code in app/src/emails/account.js
const mailgun = require("mailgun-js");
const DOMAIN = "sxxxxxxxxxxxxxxxxxxxxxxxxxxx.mailgun.org";
const mg = mailgun({apiKey: process.env.MAILGUN_API_KEY, domain: DOMAIN});
const sendWelcomeEmail = async (email, name) => {
const dataForMail = {
to: email,
from: 'zzz#xxx.com',
subject: 'Testing!',
text: `Welcome to the app, ${name}, let me know how you get along with the app.`,
}
mg.messages().send(dataForMail)
}
code in app/test/__mocks__/mailgun-js:
module.exports = {
messages() {
},
send() {
},
mailgun() {
}
}
Whenever I run jest, it says 'mailgun is not a function'. How can I create a manual mock for this constructor?
My mock is an object, not a function. Test doubles need to match the interface of the thing they're replacing; in this case, it needs to be a function that returns an object with a messages method (which returns an object with the send method). My mock doesn't match that structure at all. (Big thanks to #jonrsharpe for informing this)
mailgun-js.js needs to be edited the same way.
module.exports = function(apiKey, domain) {
const object2 = {
send() {
}
}
const object1 = {
messages () {
return object2
}
}
return object1
}

sinon.spy in my Node.JS project when testing an AWS service not working as expected

in my Node.JS project (a backend for an Angular 5 project) I have created a service that deals with the AWS Authentication... I have called this awsAuthenticationService. All works well but I now need to test it. In my awsAuthenticationService.js I have the following method that has some minor logic and then calls a method provided by the "cognitoIdentityServiceProvider". Here is a snippet of my code (I really have reduced this)
constructor() {
this._cognitoIdentityServiceProvider = new AWS.CognitoIdentityServiceProvider(this.cognitoConfig);
}
toggleUserAccess(userName, type) {
const params = {
Username: userName,
UserPoolId: this.cognitoConfig.userPoolId
};
if (type === null) {
return this._cognitoIdentityServiceProvider.adminEnableUser(params).promise();
}
return this._cognitoIdentityServiceProvider.adminDisableUser(params).promise();
}
As you can see from the toggleUserAccess we pass a few parameters, determine what they are then call the appropriate method. I wish to test this by having a unit test that will call the authenticationService.toggleUserAccess, pass some params and spy on the authenticationService._cognitoIdentityServiceProvider methods to see if they were called. I set it up so...
let authenticationService = require('./awsAuthenticationService');
describe('toggleUserAccess', () => {
beforeEach(() => {
authenticationService._cognitoIdentityServiceProvider = {
adminDisableUser(params) {
return {
promise() {
return Promise.resolve(params);
}
};
}
};
authenticationService._cognitoIdentityServiceProvider = {
adminEnableUser(params) {
return {
promise() {
return Promise.resolve(params);
}
};
}
};
});
it('should call adminEnableUser if the type is null', () => {
authenticationService.toggleUserAccess('TheUser', null);
const spyCognito = sinon.spy(authenticationService._cognitoIdentityServiceProvider, 'adminEnableUser');
expect(spyCognito.calledOnce).to.equal(true);
});
it('should call adminDisableUser if the type is null', () => {
authenticationService.toggleUserAccess('TheUser', '0001');
const spyCognito = sinon.spy(authenticationService._cognitoIdentityServiceProvider, 'adminDisableUser');
expect(spyCognito.calledOnce).to.equal(true);
});
});
My tests aren't passing and I think I have set up my sinon.spys incorrectly - can anyone see what I am doing wrong or give advice please
To stub class of AWS.CognitoIdentityServiceProvider, need to stub with its prototype keyword.
// add require statement for your AWS class
const spyCognito = sinon.spy(AWS.CognitoIdentityServiceProvider.prototype, 'adminDisableUser');
expect(spyCognito.calledOnce).to.equal(true);
Hope it helps

Express not finding route

I have the following routes defined in Angular:
export class CartService {
private cartAddUrl = "/api/cart/add";
private cartGetUrl = "/api/cart/get";
private cartCountUrl = "/api/cart/count";
}
Calls to the Node server using the first two variables work as expected. Calls using the cartCountUrl result in a 404 error, the route is not found.
This is the function that uses the cartCountUrl:
public getNumberOfItems() {
return this.httpClient.get<number>(this.cartCountUrl)
.pipe(
tap(count => console.log('count', count)),
map(count => this.numberOfItems = count)
)
}
The routes are defined on Node as follow:
'use strict';
var ctrlCart = require('../controllers/cart.server.controller');
var ctrlUser = require('../controllers/user.server.controller');
module.exports = (app) => {
app.route('/api/cart/add')
.post(ctrlUser.authenticate, ctrlCart.cartAdd);
app.route('/api/cart/get')
.get(ctrlUser.authenticate, ctrlCart.cartGet);
app.route('/api/cart/count')
.get(ctrlUser.authenticate, ctrlCart.cartCount);
}
Again, the first two routes are found. The '/api/cart/count' route results in 404 error.
cart.server.controller:
exports.cartCount = function(req, res) {
Cart.findOne({pasword: req.password})
.exec(function(err, cart) {
if(err) {
console.log('error get cart count');
res.status(500).json(err);
return;
} else if(!cart) {
res.status(404).json(0);
} else {
console.log('cart count', cart.cartItem.length);
res.status(200).json(cart.cartItem.length);
return;
}
})
}
Simple typo. In the controller, "password" was spelled with one 's'.
Cart.findOne({pasword: req.password})
I don't understand why node would report this as a routing error.

sequelize ORM asynchronous method calls

How can I call methods asynchronously in sequelize ORM? (because I have to use returned value inside other methods).
user.dao.js:
var User = require('./user.model');
class UserDao {
constructor() {}
insert(user) {
var pk;
User.sync({ force: false }).then(() => {
User.create(user).then(function(user) {
console.log('Entry successful from dao: ' +
JSON.stringify(user));
//return generated pk
pk = user.id;
console.log('ID: ' + pk);
});
});
return pk;
}
user.test.js:
class UserDaoTest {
constructor() {
this.userDao = new UserDao();
this.compare = new UtilsObject();
}
/*
all CRUD method calls
*/
testAll() {
this.testInsert();
this.testUpdate();
//this.testDelete();
//this.testRead();
//this.compare();
}
/*
insert method
*/
testInsert() {
// composite form
var user = {
name: 'nisha',
email: 'nisha#gmail.com',
phoneNo: 8978,
picUrl: 'nisha',
description: 'SI',
status: 'active',
waitingTime: 10,
rating: 7
};
/*
calling insert user with above data
*/
var pk = this.userDao.insert(user);
console.log('pk value: ' + pk);
//var obj1 = this.userDao.readById(pk);
console.log('obj1 value: ' + user);
//this.testReadById(obj1);
}
testReadById(obj1) {
var obj2 = this.userDao.readById(obj1);
this.compare.compare(obj1, obj2);
this.testDelete(obj1);
}
}
export default UserDaoTest;
Here in user.test.js, in testInsert() method want to get the value of pk which is returned from insert() method of user.dao.js, but right now I am getting pk value as undefined.
Use a promise chain.
Suppose you need to get an entry for a particular user & do some operations on it.
Model.User.findById(someId)
.then((user) => {
// Do something with user.
})
You shouldn't be calling methods synchronously, NodeJs is not designed this way. It works with callbacks or promises.
Your code won't work because it is async code.
Watch the famous Youtube video about the event loop
But in short, if you will run the following example, which is like your code but without your logic:
var User = require('./user.model');
class UserDao {
constructor() {}
insert(user) {
var pk;
console.log('1');
User.sync({ force: false }).then(() => {
pk = 123;
console.log('3');
});
console.log('2');
return pk;
}
The variable pk will be undefined and your console will look like this:
1
2
3
If you want it to work, you should "wait" for the async functions like this:
var User = require('./user.model');
class UserDao {
constructor() {}
// #return Promise
insert(user) {
return User.sync({ force: false }).then(() => {
return User.create(user)
}).then((user) => {
console.log('Entry successful from dao: ' + JSON.stringify(user));
return user.id
})
}
And when you use it:
class UserDaoTest {
constructor() {
this.userDao = new UserDao();
this.compare = new UtilsObject();
}
/*
all CRUD method calls
*/
testAll() {
// if testInsert and testUpdate can run simultaneously you can keep it like this.
// Otherwise, use Promise.then as well
this.testInsert();
this.testUpdate();
}
/*
insert method
*/
testInsert() {
var user = {
// ...
};
/*
calling insert user with above data
*/
this.userDao.insert(user).then((userId) => {
// YOUR COMPARE CODE
}).then(done); // Where done is a function to let you test framework that you async code is done
}
}
export default UserDaoTest;
Another way of doing that is using the new async and await. That way you will get a code which is more readable and maintainable.
You can read more here

Resources