NPM 'should' library causes circular reference error when calling JSON.stringify on object - json

Now I know why I avoid libraries like should that modify the object prototype
It looks like I get this error:
TypeError: Converting circular structure to JSON
when I require('should')
Is this expected?
before calling JSON.stringify, I can delete the properties from the object to be stringified like so:
delete obj.should;
delete obj.getShould;
but this is hard to do with nested objects etc. I have to say, this is pretty lame that should causes this, but maybe I am doing something wrong. How to fix this problem? I am writing a library and the user might require('should') so I have to protect against this type of issue.

Though with slightly different output, util.inspect() provides output without circular reference breaking it. Also it provides means to customize the object inspection. Will it work for you?

Should is not setting properies directly on the object, but rather on it's propotype:
Object.defineProperty(Object.prototype, 'should', {
set: function(){},
get: function(){
return should(this);
},
configurable: true
});
It must be something else that prevents an object from being serialized.

Related

why fabricjs kclass fromobject returning undefined on new version?

yesterday i have changed fabricjs version in our application. suddenly kclass.fromObject returning undefined.
my previous version is 1.7.22 and currently using 3.6.1 https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.6.1/fabric.min.js
kclass.fromobject returning undefined. but objects[i] has data.
> var klass = fabric.util.getKlass(objects[i].type);
> console.log(klass.fromObject(objects[i])); //returning undefined on 3.6.1
> fabricObj.add(klass.fromObject(objects[i]));
could you please let me know how to fix this issue?
Here is the screenshot
Your objects array contains just plain javascript objects that represent serialized Fabric objects (like path, circles, whatever).
Before rendering these plain javascript objects you need to transform them in Fabric objects. This process is called deserialization.
Your code does it, but only the if the async property of the variable klass is true.
It happens here:
var klass = fabric.util.getKlass(objects[i].type);
if (klass.async) {
klass.fromObject(objects[i], function (img) {
canvas1.add(img);
});
}
The object is deserialized, passed as an argument to the callback function and then added to the canvas, and this is great.
The problem is in the else branch of your conditional, where nothing of that happens. The only code present is this:
else {
console.log(objects[i]);
canvas1.add((objects[i]));
}
Here you are trying to add the plain object to the canvas, and that triggers an error.
One simple solution is to remove the if / else and always execute the deserialization step. If for other reasons you need to maintain the if / else conditional, you can simply deserialize the object in the else path too.
Here is a working Fiddle that preserves the conditional.
Why did it work in the previous version of Fabric? It is hard to say. Maybe that type of object was marked as async, so triggering the right path. Or maybe the canvas.add method was automatically deserializing javascript objects.

JSON Compatible Output of Whole Object and Their Invisible Properties in Node

const TelegramBot= require('./telegram-bot') // It's currently only local.
var bot = new TelegramBot()
console.log(bot)
// This does not print a complete JSON of the object. It misses stuff like
constructor, method, prototype and super_.
Is there some way or npm module that prints a JSON compatible output of the object?
My only work around so far is console logging it out like this and repeatedly checking the log and printing out another but I think it'll be a lot of easier by having a JSON export and using a JSON online viewer that views like a directory tree.
console.log(`
TelegramBot:
> ${Object.getOwnPropertyNames(TelegramBot)}
TelegramBot.prototype:
> ${Object.getOwnPropertyNames(TelegramBot.prototype)}
TelegramBot.prototype.constructor:
> ${Object.getOwnPropertyNames(TelegramBot.prototype.constructor)}
TelegramBot.prototype.constructor.super_:
> ${Object.getOwnPropertyNames(TelegramBot.prototype.constructor.super_)}
`)
I'm aware functions can't be seen with JSON.parse(). I don't mind if they appear as a string like "Anonymous Function()" or "FunctionWithAName()". Or something like this.
I'm doing this since I'm having another go trying to learn prototypes and I've used util.inherits(TelegramBot, EventEmitter) in the TelegramBot object.
To avoid name clashes between TelegramBot methods I've made and the super class of EventEmitter names. I'd like to keep a clear view of the whole object structure. Or do I not have to worry since they use this variable shadowing thing? If I'm correct it checks the object's instance first, then it's prototype. Not sure if EventEmitter prototype checked first or TelegramBot's.

getIn() not traversing an Immutable structure

I have an OrderedMap called "firebase" from the immutable-js library which has three leaf nodes:
but then I'd expect to be able to inspect the ordered map at firebase.auth with:
newValue.getIn(['firebase', 'auth'])
But that doesn't work:
Can someone help me understand what I'm doing wrong.
Your auth is an Immutable OrderedMap, but it seems that your firebase is a simple JavaScript object, not an Immutable.js one. Hence why getIn would not work. Thus newValue.get('firebase').auth would suffice.
If you are not using the redux-immutable package then you are probably going to have these (and other) issues due to combineReducers. However, combineReducers created using redux-immutable uses Immutable.js API to iterate the state so check it out.

AdvancedDataGrid - access dataProvider

I have AdvancedDataGrid and I wanted to access dataProvider.getItemAt(i) in function in my view.
I'm not getting any errors nor warning and the code is compiling, but when I run this function I get this error:
Property getItemAt not found on mx.collections.HierarchicalCollectionView and there is no default value.
Why can't I do this? I saw some samples ane people was using this function.
This is how I call it:
var x:Object = _dg.dataProvider.getItemAt(i);
The AdvancedDataGrid's dataProvider is a generic object. That, basically, means the compiler will let any property/method access on it slide without issues.
The HierarchicalCollectionView does not have a getItemAt() method, which is why you get the runtime error. The Hierarchical collection, by nature, contains nested elements I'm not sure how you'd access a single element using a single index.
You probably want to use some form of getChildren() or getParentItem() method to get access to an individual node.
The places where you saw getItemAt() work were most likely using an ArrayCollection.

How to access returned JSON object from soundcloud api

I am trying to access a json object returned from soundcloud. I can access it using the following
var myJSON = $.getJSON("http://api.soundcloud.com/users/<myuserid hidden>/tracks.json?client_id=<myclientid hidden>");
now, I know all the data has been correctly assigned to the var myJSON, as when I log it to the console, everything is there. It returns something like this:
"[{"kind":"track","id":<trackid>,"created_at":"2012/12/17 21:48:03 +0000","user_id":<myid>,"duration":185147,"commentable":true,"state".......
However, when I try to access anything like, say, the title of the first track with:
console.log(myJSON[0].title);
chrome simply gives the error Uncaught TypeError: Cannot read property 'title' of undefined
so... I am probably missing something quite basic here. Anybody got any idea as to what I'm doing wrong? Help would be very much appreciated!
EDIT: everything needs to be done inside the $.getJSON call, as such:
$.getJSON('http://api.soundcloud.com/users/<userid>/tracks.json?client_id=<client_id>', function(sounds) { **enter whatever code you want to execuse
The "function(sounds)" part is what's important to add. Apparently, it's not very straightforward to access anything you get from the JSON object outside of the .getJSON method. (there are some ways, but require some workarounds that I didn't really understand much of). soo... I needed to add all my code inside here.