I'm stuck with handling array of objects that contain errors inside my react-native/redux application.
I have a handleResponse function that looks something like this:
function handleResponse (response) {
let status = JSON.stringify(response.data.Status)
let res = JSON.stringify(response)
if (Number(status) === 200) {
return res
} else {
throw new SubmissionError('Something happened')
}
}
But instead of plain text passed as argument to SubmissionError function - I want somehow to take out errors from array of objects.
Array of objects containing error messages looks like this:
{
ErrorMessages: [
{ ErrorMessage: 'foo' },
{ ErrorMessage: 'bar' }
]
}
How can I, for example, throw foo and bar errors?
You can't really throw two things at once, unless you wrap them in a Promise or do other tricks, I would just concatenate the errors together and do a single throw:
function handleResponse (res) {
if (Number(res.data.Status) === 200) {
return JSON.stringify(res)
}
const errors = res.ErrorMessages.map(e => e.ErrorMessage).join(', ')
throw new SubmissionError(`Some errors occurred: ${errors}.`)
}
Related
try {
myObject = {
a: JSON.stringify(obj)
};
} catch (err) {
logError(`myMethod :::: ${err.message}`);
}
I wanted to cover catch block under jest testcases but I am new to this jest test cases so I m not getting how to mock Json.stringify and how to throw error?
I am mocking as below. But I am getting error as: TypeError: Invalid JSON Can u please tell me where I am going wrong?
JSON.stringify = jest.fn().mockImplementationOnce(() => { throw new TypeError('Invalid JSON'); });
As I understand it, you want to test the catch part of your code. You can pass an invalid Json as an object.
So, if your function is:
function jestTest(obj) {
try {
myObject = {
a: JSON.stringify(obj)
};
} catch (err) {
logError(`myMethod :::: ${err.message}`);
}
}
module.export = jestTest
then, in your test function, you can use this:
var jestTestObject = require('./jestTest') // this hold your exported module, code which you are testing
JSON.stringify = jest.fn(); // do not mock to return "Invalid Json"
test("CatchPart", () => {
var invalidJson = ({ "a": 1}) // Create invalid json
var logErrorSpy = jest.spyOn(jestTestObject, 'logError') // spy on logError
jestTest(obj); // Invalid object will take it to catch part
expect(logErrorSpy).toHaveBeenCalledTimes(1) // which will call logError once
})
I am trying to create a design for tags of entities in PouchDB with ReactJS. I managed to save my design using the put function, but when I query my design, the response is just an empty array and I am getting following error in console:
TypeError: Cannot read property 'emit' of undefined
I think the problem is in my function that I later use as a map parameter to my design variable:
function emitTagsMap(doc)
{
if (doc !== undefined)
{
if (Array.isArray(doc.tags))
{
doc.tags.forEach(x =>
{
/* Here is probably the problem - this.db is undefined */
this.db.emit(x, null);
});
}
}
};
this.db is declared in constructor:
constructor(service, name)
{
if (!service || !name) throw new Error("PouchDatabase initialized incorrectly");
this.name = name;
this.db = new PouchDB(name);
this.service = service;
this.tagsView();
}
Please bare in mind that I am completely new to PouchDB.
Any ideas how can I initialize the emit function?
Thank you in advance.
I assume, that your function is a part of a JavaScript class (otherwise you have to explain the idea with this). In ES6, you have to bind this to your regular functions. You have two options:
First - bind it via constructor:
constructor() {
this.emitTagsMap = this.emitTagsMap.bind(this);
}
Second - declare the function as an arrow one. This way, react will bind it for you:
emitTagsMap = (doc) =>
{
if (doc !== undefined)
{
if (Array.isArray(doc.tags))
{
doc.tags.forEach(x =>
{
/* Here is probably the problem - this.db is undefined */
this.db.emit(x, null);
});
}
}
};
You don't need to call emit over the database object.
Try this:
function emitTagsMap(doc)
{
if (doc !== undefined)
{
if (Array.isArray(doc.tags))
{
doc.tags.forEach(x =>
{
emit(x, null);
});
}
}
};
According to the PouchDB docs a design document is formed like this:
// first create a new design doc and pass your map function as string into it
var ddoc = {
_id: "_design/my_index",
views: {
by_name: {
map: "function (doc) { if (doc !== undefined) { if (Array.isArray(doc.tags)) { doc.tags.forEach(x => { emit(x, null); }); } } }"
}
}
};
// save it
db.put(ddoc).then(function () {
// success!
}).catch(function (err) {
// some error (maybe a 409, because it already exists?)
});
//Then you actually query it, by using the name you gave the design document when you saved it:
db.query('my_index/by_name').then(function (res) {
// got the query results
}).catch(function (err) {
// some error
});
https://pouchdb.com/guides/queries.html
I have the following method which isn't working correct:
getProducts(): Observable<Product[]> {
let PRODUCTS: Product[];
this.http.get(this.base_url + "api/products")
.subscribe(
(data) => {
for(var i in data) {
PRODUCTS.push(new Product(data[i].id, data[i].name, data[i].category, data[i].description, data[i].price, data[i].amount));
}
},
(error) => {
console.log(error);
});
return of(PRODUCTS);
}
The error I'm getting is this:
TypeError: Cannot read property 'push' of undefined
Now, I know that the PRODUCT array is not accessable from within the subscribe function, but I cannot get the correct solution for it.
Can anyone help me with that. I want to return an Observable<Product[]>.
Thank you in advance!
Edit: Updated to account for the fact that the API seems to return an array-like object rather than a true array.
You want to use map:
getProducts(): Observable<Product[]> {
return this.http.get(this.base_url + "api/products")
.map(data => {
let products = [];
for (let i in data) {
products.push(new Product(data[i].id, data[i].name, data[i].category, data[i].description, data[i].price, data[i].amount));
}
return products;
})
.do(null, console.log);
}
Since #pixelbit's comment keeps getting upvotes despite being wrong, here's an example showing why it is wrong:
// Fakes a HTTP call which takes half a second to return
const api$ = Rx.Observable.of([1, 2, 3]).delay(500);
function getProducts() {
let products = [];
api$.subscribe(data => {
for (let i in data) {
products.push(data[i]);
}
});
return Rx.Observable.of(products);
}
// Logs '[]' instead of '[1, 2, 3]'
getProducts().subscribe(console.log);
I have this weird scenario which I do not know what the problem is exactly. While troubleshooting I found out that the subscription is published and subscribed to because it's printed on the console. When I executed this on Firefox console it displayed this error SyntaxError: missing : after property id [Learn More]. I don't know what the syntax error is as the same code works on other files.
If I remove fetch() function from it it displayed 2 obects being published. This means the publish and sbscription is working. What am I to do right?
This is the event function
students(){
let myslug = trimInput(Session.get('ReceivedSlug'));
if (myslug) {
let mySchoolDoc = SchoolDb.findOne({slug: myslug});
if (mySchoolDoc) {
let arrayModuleSchool = StudentSchool.find({schoolId: mySchoolDoc._id});
if (arrayModuleSchool) {
var arrayStudentIds = [];
arrayModuleSchool.forEach(function(studentSchool){
arrayStudentIds.push(studentSchool.studentId);
});
let subReadiness = SchoolStudents.find({ _id: {$in: arrayStudentIds}}).fetch();
if (subReadiness) {
console.log('before readiness --- ' +arrayStudentIds);
console.log('after seting --- ' +subReadiness);
return subReadiness;
}
}
}
}
}
This is the publish function
Meteor.publish('PaginatedStudents', function (skipCount) {
check(skipCount, Number);
user = Meteor.users.findOne({_id:this.userId})
if(user) {
if(user.emails[0].verified) {
return SchoolStudents.find({userId: this.userId}, {limit: 2, skip: skipCount});
} else {
throw new Meteor.Error('Not authorized');
return false;
}
}
});
Tracker to rerun when things changes
Session.setDefault('skip', 0);
Tracker.autorun(function () {
Meteor.subscribe('PaginatedStudents', Session.get('skip'));
});
I am going through John Papa's SPA course on pluralsight and I am running into error that say The 'structuralTypeName' parameter must be a 'string' while using breeze. Here is the actual error that is being thrown
The code that is generating this error is metadataStore.getEntityType:
function extendMetadata() { names
var metadataStore = manager.metadataStore;
var types = metadataStore.getEntityType();
types.forEach(function(type) {
if (type instanceof breeze.EntityType) {
Set(type.shortName, type)
}
});
function set(resourceName, entityName) {
metadataStore.setEntityTypeForResourceName(resourceName, entityNames);
}
it is called by my prime function.
function prime() {
if (primePromise) return primePromise //if primePromise was loaded before, just return it
primePromise = $q.all([getLookups()])
.then(extendMetadata)
.then(success);
return primePromise;
function success() {
setLookups();
log('Primed the data');
}
I'm unsure what the problem is with the breeze call. Any insight into how to fix this? Thanks for your help community.
Nick
Here is the lookups query info:
function setLookups() {
var entityNames = {
personnel: 'Personnel',
cto: 'Cto',
kkeys: 'Kkey',
promotion: 'Promotion',
loa: 'Loa'
};
service.lookupCachedData = {
ctos: _getAllLocal(entityNames.cto, 'ctodate' )
kkeys: _getAllLocal(entityNames.kkeys, 'keystamp'),
promotions: _getAllLocal(entityNames.promotion, 'pdate'),
loas: _getAllLocal(entityNames.loa, 'lstrdte')
}
}
function _getAllLocal(resource, ordering) {
return EntityQuery.from(resource)
.orderBy(ordering)
.using(manager)
.executeLocally();
}
function getLookups() {
return EntityQuery.from('Lookups')
using(manager).execute()
.then(querySucceeded, _queryFailed)
function querySucceeded(data) {
log('Retrieved [Lookups] from remote data source', data, true);
return true;
}
}
function _queryFailed(error) {
var msg = config.appErrorPrefix + 'Error retrieving data from entityquery' + error.message;
logError(msg, error);
throw error;
}
You have to pass in a string to getEntityType. Sorry I missed that the first time through.
metadataStore.getEntityType('cto');
Also you are going to blow up when you are trying to call Set() function but the functions name is set() and also set is probably a keyword you aren't trying to override.