I'm getting this error, but I've checked and tested the strings and they are exactly the same:
Expected { $$state : { status : 1, value : { customerNumber : 'customerNumber', name : 'name', userId : 'buId', customerType : 'type', address : 'displayAddress' } } }
to equal { $$state : { status : 1, value : { customerNumber : 'customerNumber', name : 'name', userId : 'buId', customerType : 'type', address : 'displayAddress' } } }.
Error: Expected { $$state : { status : 1, value : { customerNumber : 'customerNumber', name : 'name', userId : 'buId', customerType : 'type', address : 'displayAddress' } } } to equal { $$state : { status : 1, value : { customerNumber : 'customerNumber', name : 'name', userId : 'buId', customerType : 'type', address : 'displayAddress' } } }.
at C:/customerServiceSpec.js:70
The only thing I can notice is there is a full stop at the end, but I think Jasmine is adding that in the response. Here is my test code:
describe('CustomerService', () => {
var mockUserSession: any = {};
var testService any = {};
var $q: ng.IQService;
var createCustomerDetailsService;
var customerDetailsService;
var createResolvedPromise;
var createRejectedPromise;
var resolvePromises;
var testResponse = {
customers: {
displayCustomerNumber: 'customerNumber',
name: 'name',
id: 'id',
type: 'type',
displayAddress: 'displayAddress'
}
};
var serviceResponse={
$$state: {
status: 1,
value: {
customerNumber: 'customerNumber',
name: 'name',
id: 'id',
customerType: 'type',
address:'displayAddress'
}
}
};
var rootScope;
beforeEach(() => {
module('app.customer');
inject(( _$q_, $injector) => {
this.$q = _$q_;
rootScope = $injector.get('$rootScope');
createResolvedPromise = (result) => {
return () => {
return this.$q.when(result);
};
};
resolvePromises = () => {
rootScope.$digest();
};
createCustomerDetailsService = () => {
return new app.customer.CustomerService(
testService);
};
});
});
it('WILL search by customer ID and return a customers details', () => {
var searchResponsePromise;
testService.getCustomerDetails = jasmine.createSpy("getCustomerDetails").and.callFake(createResolvedPromise(testResponse));
customerDetailsService = createCustomerDetailsService();
searchResponsePromise = customerDetailsService.getCustomerDetails('12345678');
resolvePromises();
expect(searchResponsePromise).toEqual(serviceResponse);
});
});
And here is my service:
public getCustomerDetails(customerID:string): ng.IPromise<ICustomerDetails> {
return this.testService.getCustomerDetails(customerID).then((customerResponse:ICustomerResult) => {
var customer = customerResponse.customers;
var customerDetailsResult:ICustomerDetails = {
customerNumber: customer.displayCustomerNumber,
name: customer.name,
userId: customer.buId,
customerType: customer.type,
address: customer.displayAddress
};
return customerDetailsResult;
});
}
Thanks for any help.
This happens due to the fact that json objects are actually different instances of objects, but they contain the same data. You need to do something like this:
expect(angular.equals(searchResponsePromise, serviceResponse)).toBe(true);
See AngularJS + Jasmine: Comparing objects for the preferred way of doing this. Essentially, you want to use expect(...).toEqual(...) instead of expect(...).toBe(...). toEqual() performs a deep comparison.
The advantage to doing this over the accepted answer is the error for a failed assertion with toBe(true) will simply say something along the lines of, expected false to be true, which isn't enough information to fix the problem.
The deep comparison performed by toEqual() will result in an assertion error containing both the expected and actual objects, serialized as strings. It makes it much nicer and easier to fix the problem. :)
Related
This is the part of the code that throws the error :
session.subscribe("acme/channel", function(uri, payload){
console.log("Received message", payload.author);
var myObject = {
'content': payload.message,
'author': { 'username' : payload.author },
}
var newMessages = this.state.messages;
newMessages.push(myObject);
this.setState({messages: newMessages});
}.bind(this));
I don't know why but it doesn't like it when I use 'author': { 'username' : payload.author }, but it work with a hard coded string like this one : 'author': { 'username' : "Mit" }.
The problem isn't coming from "payload.author" because this also works:
var myObject = {
'content': payload.author,
'author': { 'username' : "Mit" },
}
Any idea how to fix this ?
It worked by adding an empty string:
var myObject = {
'content': payload.msg,
'author': { 'username' : payload.author + ""},
}
I don't know why it does that, if someone has a better explanation I can mark his answer.
I'm trying to build an application using MEAN but now I'm stuck when trying to find linestrings intersecting on another one given its name.
For instance, given the following image, poly1 and poly2 should have intersections while poly3 does not.
Let's suppose poly1 has the following coordinates and the following JSON:
{
"_id" : ObjectId("57ab2107505ab11b1bd8422e"),
"name" : "poly1",
"updated_at" : ISODate("2016-08-10T12:41:43.789+0000"),
"created_at" : ISODate("2016-08-10T12:41:43.780+0000"),
"geo" : {
"coordinates" : [ [14.59, 24.847], [28.477, 15.961] ],
"type" : "LineString"
},
"__v" : NumberInt(0)
}
When I run the query on MongoChef I find both poly1 and poly2 and I do not find poly3 like I want:
{
geo :{
$geoIntersects:{
$geometry :{
type: "LineString" ,
coordinates: [ [14.59, 24.847], [28.477, 15.961] ]
}
}
}
}
While, when I run the query on Mongoose given a Polyline Id/name it does not work
//Given
var linestringById = Linestrings.find({name : lineName});
var linestrings = Linestrings.find({});
//Works
query = linestrings.where({ geo : { $geoIntersects :
{ $geometry :
{ type : 'LineString',
coordinates : [ [27.528, 25.006], [14.063, 15.591] ]
}
} } });
//Does not work
query = linestrings.where({ geo : { $geoIntersects :
{ $geometry :
{ type : 'LineString',
coordinates : linestringById.geo.coordinates
}
} } });
//Also does not work:
query = linestrings.where({ geo : { $geoIntersects :
{ $geometry :
{ type : 'LineString',
coordinates : linestringById
}
} } });
This is the Schema for LineStrings:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
// Creates a LineString Schema.
var linestrings = new Schema({
name: {type: String, required : true},
geo : {
type : {type: String, default: "LineString"},
coordinates : Array
},
created_at: {type: Date, default: Date.now},
updated_at: {type: Date, default: Date.now}
});
// Sets the created_at parameter equal to the current time
linestrings.pre('save', function(next){
now = new Date();
this.updated_at = now;
if(!this.created_at) {
this.created_at = now
}
next();
});
linestrings.index({geo : '2dsphere'});
module.exports = mongoose.model('linestrings', linestrings);
This is how I call the query from the front-end QueryController.js
/** Looks for LineStrings intersecting a given linestring **/
vm.polyIntersect = function () {
//Taking name from a form
vm.queryBody = {
name : vm.formData.poly1
};
// Post the queryBody
$http.post('/find-poly-intersection', vm.queryBody)
.success(function(queryResults) {
console.log(queryResults);
})
.error(function(queryResults) {
console.log('Error: no results found '+queryResults));
});
};
This is my Route.js:
/** Requiring Factories **/
var LinestringFactory = require('./factories/linestring.factory.js');
module.exports = function(app) {
// Retrieves JSON records for all linestrings intersecting a given one
app.post('/find-poly-intersection', function(req, res) {
LinestringFactory.findIntersections(req).then( function (linestrings) {
return res.json(linestrings);
}, function (error) {
return res.json(error);
})
});
}
This is my LineString.factory.js:
var Linestrings = require('../models/linestring-model.js');
exports.findIntersections = findIntersections;
/** Finds Linestrings Intersections **/
function findIntersections(req) {
return new Promise( function (resolve, reject) {
var lineName = req.body.name;
var linestringById = Linestrings.find({name : lineName});
var linestrings = Linestrings.find({});
//Check if that certain linestring exists with Lodash
if (_.isEmpty(linestringById) || _.isUndefined(linestringById)
|| _.isNull(linestringById)){
return reject('No Linestrings found for that Name');
} else {
query = linestrings.where({ geo :
{ $geoIntersects : { $geometry :
{ type : 'LineString',
coordinates : linestringById.geo.coordinates}
} } });
query.exec(function (err, intersections) {
if (err){
return reject(err);
}
return resolve(intersections);
});
}, function (error) {
return reject(error);
})
}
console.log in QueryController gives me always Object {} for any
linestring name.
This is the Mongoose Log of the query.
I'm making sure of inserting [lng, lat] coordinates
Have you any idea on why I can't find any LineString intersecting by Id while I can find them using straight coordinates?
Thanks in advance.
You are passing linestring.geo.coordinates in latitute,longitute format to the final query.
Mongodb accepts coordinates in the x,y format, hence it has to be longitude,latitude
Updated:
You will need to directly pass the linestring as $geometry.
query = linestrings.where({ geo : { $geoIntersects :
{
$geometry : lineStringbyId.
} } });
I finally managed to solve this issue with the following code
/** Finds Linestrings Intersections **/
function findIntersections(req) {
return new Promise( function (resolve, reject) {
var lineName = req.body.name;
Linestrings.findOne({name : lineName}).then( function (linestringById, error) {
if(error){
return reject({error : 'LineString not Found'});
}
queryIntersections(linestringById).then( function (response) {
return resolve(response);
});
});
}, function (error) {
return reject({error : 'Error while executing promise'});
});
}
function queryIntersections(linestringById) {
return new Promise( function (resolve, reject) {
if (_.isEmpty(linestringById) || _.isUndefined(linestringById) || _.isNull(linestringById)){
return reject({ error : 'No Linestrings found for that Name'});
} else {
query = Linestrings.where( { geo : { $geoIntersects : { $geometry : { type: 'LineString', coordinates: linestringById.geo.coordinates } } } } );
queryExec(query).then( function (intersections) {
return resolve(intersections);
});
}
}, function (error){
return reject({error : 'Error while executing promise'});
});
}
The error was caused by the fact that I did not pass correctly linestrings and linestringById objects to the query.
I hope it will help someone.
I have the following factory to send query to server:
app.factory('Request', ['$resource',
function ($resource) {
var res = $resource("bin/server.fcgi/REST/" + ':resourceName/:ID', {}, {
get : {
method : 'GET'
},
put : {
method : "PUT"
}
});
return {
get : function (arguments, b, c) {
return res.get(arguments, b, c).$promise;
},
put : function(arguments,b,c){
return res.put(arguments, b, c).$promise;
}
};
}
]);
I call it like this:
Request[methodName](params).then(successFunction).catch (failFunction);
However, if i want to send a PUT query:
Request["put"](params).then(successFunction).catch (failFunction);
where
params = {
resourceName : "ATable",
ID : 222,
AProperty : "changedValue"
}
I take then following request: (so an error)
http://myadres.com/REST/ATable/222?AProperty=changedValue
instead of
http://myadres.com/REST/ATable/222
with payload
{ AProperty:changedValue }
What is wrong with this?
app.service('Request', ['$resource',function ($resource) {
var res = $resource('bin/server.fcgi/REST/:resourceName/:ID',
{resourceName: "#resourceName", ID: "#ID"},
{
get : { method : 'GET'},
put : { method : "PUT", params: {resourceName:"#resourceName", ID: "#ID"}//you can leave the string empty if you dont want it to be a defualt value like ID:""
});
this.get = function () {
return res.get().$promise;
}
this.put = function(obj){
return res.put(obj).$promise; // it can be also {like json with your params}
}
]);
and then call it from controller by
var obj = {
ID:222,
resourceName:'ATable'
}
Request.put(obj).then(function(data){
//check whats the data
})
this is how it should be done
maybe not the best way but should work
I want to convert this object:
$scope.foo = {
bar: {
baz: 'foobarbaz'
}
}
to
foo[bar][baz]=foobarbaz
query string.
Also how to convert
$scope.fields = ['id', 'name', 'created_at']
to
fields[]=id&fields[]=name&fields[]=created_at`
Is there any library or function in Angularjs to do this job?
No need to write those serializers yourself, Angular has the one built-in for you. imply inject $httpParamSerializerJQLike service and use it:
$scope.foo = {
foo: {
bar: {
baz: 'foobarbaz'
}
}
};
$scope.fields = {
fields: ['id', 'name', 'created_at']
};
console.log( $httpParamSerializerJQLike($scope.foo) );
// => "foo[bar][baz]=foobarbaz"
console.log( $httpParamSerializerJQLike($scope.fields) );
// => "fields[]=id&fields[]=name&fields[]=created_at"
// (output shown URL-decoded)
Take a look at this
function toPhpQuery(obj) {
return Object.keys(obj).map(key => {
var val = obj[key];
var prefix = encodeURIComponent(key);
return Array.isArray(val)
? _toPhpQueryArray(val, prefix)
: _toPhpQueryObject(val, prefix);
}).join("&");
function _toPhpQueryArray(arr, prefix) {
return arr.map(v => prefix + "[]=" + encodeURIComponent(v)).join("&");
}
function _toPhpQueryObject(value, prefix) {
if (typeof value === "object" && value) {
return Object.keys(value).map(k => _toPhpQueryObject(value[k], prefix + "[" + encodeURIComponent(k) + "]")).join("&");
} else {
return prefix + "=" + encodeURIComponent(value);
}
}
}
console.log(toPhpQuery({
foo: {
bar: {
baz: 'foobarbaz'
}
},
fields: ['id', 'name', 'created_at']
}));
I have the following code to filter a grid from values inputed in a form on a click of a button. The problem is that the first time the filters are activated, only the first filter (displayNameFilter) will be included in the request.
The second time and on, both filters will be included in a request. How can I work around that issue?
var nameFilter = grid.filters.getFilter('name');
if (!nameFilter) {
nameFilter = grid.filters
.addFilter({
type : 'string',
dataIndex : 'name'
});
}
nameFilter.setValue(Ext.getCmp('name-filter').getValue());
var displayNameFilter = grid.filters.getFilter('displayName');
if (!displayNameFilter) {
displayNameFilter = grid.filters
.addFilter({
type : 'string',
dataIndex : 'displayName'
});
}
displayNameFilter.setValue(Ext.getCmp('display-name-filter').getValue());
displayNameFilter.setActive(true, false);
nameFilter.setActive(true, false);
I had a similar problem. The solution is a bit hokey but it works for me, notice that the filter variable is defined a second time within the defer call (it is needed):
grid.filters.createFilters();
var nameFilter = grid.filters.getFilter('name');
if (!nameFilter) {
nameFilter = grid.filters
.addFilter({
type : 'string',
dataIndex : 'name'
});
}
nameFilter.setActive(true);
var displayNameFilter = grid.filters.getFilter('displayName');
if (!displayNameFilter) {
displayNameFilter = grid.filters
.addFilter({
type : 'string',
dataIndex : 'displayName'
});
}
displayNameFilter.setActive(true);
Ext.Function.defer(function() {
nameFilter = grid.filters.getFilter('name');
nameFilter.setValue(Ext.getCmp('name-filter').getValue());
displayNameFilter = grid.filters.getFilter('displayName');
displayNameFilter.setValue(Ext.getCmp('display-name-filter').getValue());
}, 10);
This worked for me:
handler : function() {
var filters = [];
// get filters from a form...
var values = filterForm.getValues();
for (var f in values) {
var value = values[f];
if (value) {
filters.push({ property: f, value: value });
}
}
//...and add all of them to the store used by the grid directly
if (filters.length) {
// prevent events firing here...
gridStore.clearFilter(true);
// ...because they will fire here
gridStore.filter(filters);
} else {
gridStore.clearFilter();
}
}