Nodejs - extend command doesn't work as expected - javascript

I've encountered a weird situation, I've been using the extend library and the _.extend command from underscore, in the following way:
var extended = extend({}, objA, objB);
I get only properties from one of the objects in the result, is there anything about extend that might be preventing it from getting all the properties from both objects?
I've used this pattern everywhere and it seemed to work as expected so far. Both are plain objects, not arrays or functions.
EDIT: I tried to make a demo, but it seems to work with both jQuery and Underscore - http://jsfiddle.net/x4UHQ/2/
While making the demo (from the objects I printed in my logs), I noticed one that when printed in console.log didn't appear as a string - it's a mongoose type of ObjectId, maybe that's somehow causing the problem? (that specific field exists in the output object, so I don't know)
UPDATE: this was the solution - UnderscoreJS wont extend object (add a lean option to the mongoose query - because that's somehow makes the object incompatible with underscore.

Sorry for new response, it better fits as comments for Madd0g response (but i don't have required reputation points for it).
You are right, it is fault of mongoose object, {lean: true} is one option to fix it, other options is calling mongooseObj.field.toJSON() - in some case it is more convenient method. For example if you have user object in controller (from auth middleware), and you need to transform some fields, then you don't need to refetch model from db.

So the problem was that one of the objects was an object from the mongoose library, it made extend commands break, the fix was to get the db object from mongoose with the lean option.
something like personModel.find({fname: "Joe"}, null, { lean: true })

Related

Instantiating a class dynamically from a string

Good afternoon fellow developers,
I am currently trying to develop a function that instantiates business objects dynamically based on the value of the string it receives as a parameter. I know this can be done in JavaScript as I have done it before and, just to be sure, I even tested it again in Visual Studio Code after having encountered this issue in my SAPUI5 app. My function's code looks somewhat like this:
createObject: function (sObject) {
var newObject = new this[sObject]();
// var newObject = new [sObject](); I also tried this way.
};
For the sake of testing this function, the sObject string currently contains the hardcoded value "Order" and I am importing my Order.js object into the file where i'm trying to instantiate this objects dynamically. No matter what I try I keep getting this error when debugging my code:
TypeError: this[sObject] is not a constructor
I was wondering if some of you might have tried something similar before and might be able to point me in the right direction. Even if there are ways for me to work around this issue, it would be really nice if I learnt how to do this dynamically since I was planning on using this approach on several different scenarios. I look forward to reading from you!
It is a really unsafe practice to instantiate objects from a string and an ATROCIOUS one to do it from a parameter a user can supply. If you have a limited set of objects its much safer to have a big switch statement.
switch(name) {
"objA": return new ObjA();
}

Load multiple i18n properties into an array possible? (JavaScript)

I have to load multiple I18N-properties that have the same sharing content into an array. I've tried
arrayIDs = oBundle.getText().includes(".id.");
It said that it can't read the property 'includes' of undefined. Most likely because there isn't anything in getText(). But this has to be variable. This method is made for one property, is there something where I can get multiple properties?
edit: nvm I solved it... If you have the same problem: I discovered
oBundle.aPropertyFiles[0].getKeys();
for myself and this gets all the keys of the I18N properties you need. After that you can make oBundle.getText(key) to get the according text and implement your own filtering logic.

How to define Matrix/Link/Cross Table joins in BreezeJS Metadata?

I'm trying to get breeze working with hand generated Metadata, but I can't seem to find documentation covering navigation properties through matrix tables.
the data model is:
Organization
PK:OrganizationID
User
PK:UserID
The table that joins them is:
User_Organization
PK:UserOrganizationID
FK:OrganizationID
FK:UserID
When I retrieve an Organization I want it to have a property "users" which contains an array of User objects.
How do I define this and specify the matrix table in Breeze Metadata, seeing as User does not have an organizationID?
** update
My primary problem is that I'm linking Breeze to Sequelize, so I need to be able to manage this all through the metadata if possible. The first answer below from #Jeremy-Danyow solves the problem with client side code, but I'm looking for a way to present the final object graph to breeze as part of the metadata.
I think this question might be a duplicate of Many-to-many relations in Breeze. There is useful information in the answer there as well as the comments on the answer.
That said, I want to propose a work-around for this part of your question:
When I retrieve an Organization I want it to have a property "users" which contains an array of User objects.
If you were to configure your metadata the supported way you could add a read-only "users" property to your organization entity like this:
function Organization() { }
Organization.prototype.users = function () {
return this.userOrganizations().map(function(userOrganization) { return userOrganization.user() });
};
store.registerEntityTypeCtor('Organization', Organization);
This uses the "Add methods to the constructor" approach documented here.
Edit
Sounds like breeze-sequelize support is in the works and will be released soon. See here and here. If you can afford to wait a little bit you'll have less friction getting this going.

"Uncaught TypeError: Converting circular structure to JSON" -- Alternatives to JSON.stringify()?

I am using a library, Instafeed, which creates a feed object. The feed object is pretty complex.
I need to convert this object to a string value for transfer.
Problem is, I'm getting the Uncaught TypeError: Converting circular structure to JSON. All of the answer I've come across say to alter the object to get rid of the circular reference. However, the object is pretty complex and I'd rather not have to do that.
Is there any other way to serialize this object that would avoid the circular reference error?
EDIT
Actually, I'm looking at the object in the console and I see this:
I expanded the context key 30 times in total and it just kept going. I'm not having memory issues, and the feed does run fine as intended with the loading of the images as the only delay, so it doesn't seem like this library creating an infinite loop of nested elements.
Is this just a peculiarity of how the object gets displayed and not indicative of the structure of the object itself?
And how do I serialize something like this?
ALSO, I tried a JSON-to-XML plugin but on conversion with that I got the following error:
Uncaught RangeError: Maximum call stack size exceeded
Examining https://github.com/stevenschobert/instafeed.js/blob/master/src/instafeed.coffee, it looks as though the context property will sometimes, but not always, be a circular reference. The one thing context is guaranteed NOT to be is null.
Test for the circular reference while serializing, and if found, serialize it as null. Deserialize on the other side by re-circularizing it.
(This is an answer only to the specific case, not the general - this object has the good grace to be IMMEDIATELY circular. A multi-step circle would be rather more complicated)
JSON is a data format, not a means of saving arbitrary JavaScript objects. So trying to push a JS object which is more than just data over the network via JSON sounds fraught. You might consider whether your design could move just the information that you actually need to move.
That said, it does look like at least one person has tried to solve the circular reference problem in library form.
If you're specifically looking for alternatives, you should check out the Circular JSON package.
Replace your calls to JSON with CircularJSON:
function MyCircularClass() {
this.circular = this;
}
var obj = new MyCircularClass();
var objSerialized = CircularJSON(obj);
console.log(obj);
// ouputs '{ "ciruclar": "~" }'
Here's your silver-bullet: cycle.js. If you're using npm it's available as a package too.
You can use it to de-cycle the object so that it can be serialized with:
var stringForm = JSON.stringify(cycle.decycle(myObject));
Later if you're loading the object back into javascript you can make it cycled again with:
cycle.retrocycle(JSON.parse(stringForm));

Backbone.js: "Remove nonexistent models if appropriate" fails

I don't know how to ask this but I'll try to be as specific and as comprehensible as I can.
I am working on application based on Backbone and Marionette which is fetching data from back-end api server. We have got some input field with auto-completion which works fine but just first time. Second time I'd type something the auto-complete crashes. Ehm, not exactly the auto-complete but the backbone.js itself. I am getting this error:
Uncaught TypeError: Cannot read property 'cid' of undefined backbone.js:716
_.extend.set backbone.js:716
Backbone.Collection.set backbone-relational.js:1851
_.extend.fetch.options.success backbone.js:860
Backbone.Paginator.Paginator.requestPager.Backbone.Collection.extend.sync.queryOptions.success backbone.paginator.js:840
jQuery.Callbacks.fire jquery.js:3073
jQuery.Callbacks.self.fireWith jquery.js:3185
done jquery.js:8251
jQuery.ajaxTransport.send.callback jquery.js:8598
Probably between two calls to retrieving data from api server I somewhere forget to "reset" retrieved model collection - I am very new to Backbone development so it is really possible.
I am sorry for not providing code samples but I want you to ask also something else - it is about how Backbone algorithm for "Remove nonexistent models if appropriate" works - can be found here https://github.com/jashkenas/backbone/blob/master/backbone.js#L734
I was curious why my code crashes so I started to debugging backbone script itself (maybe not so good idea as it looks but I found out something interesting). In the provided link above you can see that backbone is iterating through models and deletes everything that is not needed. Its O.K. but I think that there is bug because backbone tries to iterate N times where N is this.length instead of this.models.length. In my case this two lengths are different. In my models I have for example 2 models but backbone tries to iterate 4 times because the value of this.length is 4.
Could please anybody explain to me why are these values different? I assume that this.length should be updated any time the length of this.models changes but in my case this is not happening.
Any ideas?
If you're doing a collection.fetch() somewhere try replacing it with collection.fetch({reset: true}) - it worked for me.

Categories

Resources