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();
}
Related
I have a schema object that contains the typed property that starts empty.
const schema = {
typed: {},
// ...
}
schema.typed will be filled dynamically when the application starts, example
typed['name'] = 'Yung Silva'
typed['age'] = 22
in another moment
typed['facebook'] = 'fb.com/yungsilva'
typed['whatsapp'] = 81981355509
there is no pattern, really each time the application is started it will be a totally different and random structure.
I would like to get an interface for this object that was dynamically assembled, example
type Fields = typeof schema.typed
it is possible?
is disturbing me at the beginning, at the moment to create the object dynamically, I don’t know what type to define for schema.typed
This is not possible since Typescript "checks" your types at compile time.
"The goal of TypeScript is to help catch mistakes early (before running the code, at compile time) through a type system and to make JavaScript development more efficient." more
At runtime the code that runs is a normal (sorta) javascript code.
there are several libraries (typescript-is) that can help you check types at run time, but the common use case doesn't need them.
TypeScript is about type checking ahead of runtime. Its purpose is to check the code consistency with itself and the third party library it uses, before running it. TypeScript won't be able to assign a type depending on the actual data, because it simply doesn't exist anymore at run time. When you write will be a totally different and random structure that means you're using plain JavaScript and its dynamic nature, so if your data never has common parts, just don't type it at all (or as any).
My client builds their own app based on Chromium, their navigator.appVersion is AppleWebkit/534+
But to my surprise they replace javascript standard built-in objects with their own, for example, check their Map bellow,
Their Map has methods like,
arr:Array[0]
isEmpty:function
remove:function
But no standard Map method like has, keys, values, check here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map (BTW, the reason we need Map here instead of plain js object is we need the key to be something other than string)
I am curious, how did they do that? Why would someone want to do that!!
And more importantly how do I restore the build in version ?
I had the same issue that the global function has been overwritten.
My trick is to use the contentWindow of an iframe to get the original function back:
Here's the code, it doesn't work in code-snippets of StackOverflow due to iframe policy, but it should work with your environment:
// contaminated Map
Map = function() {
this.foo = 'bar';
}
const map1 = new Map();
console.log(map1);
// restoring Map
const iframe = document.createElement('iframe');
document.body.append(iframe);
const OriginalMap = iframe.contentWindow.Map;
iframe.remove();
const map2 = new OriginalMap();
map2.set('foo', 'bar');
console.log(map2);
Here's the screenshot shows that it works:
This is more like a workaround, not sure if there's a better way to do it.
how did they do that?
It's as simple as:
Map = function() { ... }
Why would someone want to do that!!
As other comments have guessed, probably because the code is older than the availability of built-in Map. If the same code is also supposed to run on older browsers, then this consideration might still be relevant.
how do I restore the build in version ?
The suggestion in the other answer is an interesting idea... I can't think of a better way.
That said: I'm guessing your task is to make extensions/modifications to an existing codebase. Having two different Maps in the same codebase sounds pretty confusing -- for anyone working on this code after you (which may be yourself, in a couple of months), it'll be pretty hard to understand what's going on. So I offer another suggestion: don't just locally get the built-in Map, and instead pick either of:
modernize the whole system to use built-in JavaScript Maps. Replace all uses of the handcrafted Map, and then delete that definition. Use built-in Map everywhere. (Check with your client though whether they are okay with you spending your time on this.)
stick with what's there, and use the handcrafted Map in your new code as well. While its functions have different names, it seems that all the important features are there. You can probably find an example of how to iterate over such a map. (This would still leave the above alternative as a future option.)
I've been serching the net for quite some time and maybe there is no solution for my problem but I hoped you might be able to help me. I'm currently trying to establish a connection to CatiaV5 via JavaScript. The connection itsself is working just fine. Basically it looks like this now:
var catia = new ActiveXObject('CATIA.Application');
var doc = catia.ActiveDocument;
But here's my problem. The returned object is a Collection in VB and there seems to be no DataType equivalent to this. So this is what i get when i try to read my variables. For example:
doc.Product
returns
[object] {};
So this seems to be empty. However if then I try to get
doc.Product.Name
which by that logic should be undefined, instead i get
"Part1"
so the correct name of my Part/Product is returned.
All the Catia stuff probably isn't that relevant for the question.
my question: Is there any way to somehow parse a VB-Collection on a JavaScript object or something similar, to get the contents of what is returned?
OK,
here's the thing. I found out, that you can't really browse throug ActiveXObjects directly in the console in general. In the IE-Dev-Tools i was however able to use the Locals-Watch to browse through the Object. I didn't find a nice way to Parse it onto a JSON-Object, however the manual way to create a new Object and add the Keys piece by piece works.
I have some experience with JavaScript - but mainly with some small stuff, I never did anything really big in Javascript previously.
Right now, however, I'm doing quite a large javascript-related project, a jquery-powered frontend that communicates with the server-side backend by sending/receiving JSON via Ajax.
I'm wondering if you could provide some useful information on how to deal with large javascript projects - are there any helpful tools/libaries/good practices?
Thanks in advance.
My one big tip would modularize
In JavaScript, it is very easy for variables to clobber other variables. In order to avoid this, modularization is a must. There are several ways to take advantage of JavaScripts scope rules to minimize the possibility of variable conflicts.
var myProject = {};
myProject.form = function(p_name, p_method, p_action)
{
var name = p_name,
method = p_method,
action = p_action;
var addInput = function(p_input)
{
// etc...
}
return {
addInput: addInput,
name: name
};
}
myProject.input = function(p_name, p_type, p_value)
{
var name, method, value;
var setValue = function(p_value)
{
value = p_value;
return true;
}
return {
setValue: setValue,
name: name
};
}
// etc...
If you're careful about using var, and keep track of your function scope, then you have only one global variable - myProject.
In order to get a new form Object, you'd simply do the following: var myForm = myProject.form('form1', 'post', 'post.php').
You may want to check out Backbone.js
Backbone supplies structure to
JavaScript-heavy applications by
providing models with key-value
binding and custom events, collections
with a rich API of enumerable
functions, views with declarative
event handling, and connects it all to
your existing application over a
RESTful JSON interface.
Grigory ,
Even i moved from a backend to UI few months back only follow this approach
read all the concepts of jquery
either from google or through some
book or through jquery
documentation.
follow some of the jquery best practices http://psdcollector.blogspot.com/2010/03/77-best-jquery-tips-i-have-ever-read.html
write utitlity functions for all repeated code like getcookie ,subsstrings etc etc
keep getting your code reviewed by experienced person who can guide you
post to stackoverflow if you get stuck anywhere.
as it is big project divide into mutiple files and use proper naming convintion.
please let me know if you need anything else
jQuery and YUI 3: A Tale of Two JavaScript Libraries is a nice comparison of them in the context of a complex application, and gives useful hints for jQuery programmers as well.
The best advice is to keep your code segmented in different files as "classes". I personally hate working in a file that's more than a few hundred lines long.
Then assemble and minify your code with one of the tools on the web, like Shrinksafe or Google Closure Compiler
Note that Dojo, YUI, and Ext are all designed to handle large Ajax applications. You'll struggle a bit with jQuery. But I'm guessing this app isn't all that big and you should be fine.
Have you consider checking out MooTools?
MooTools is a compact, modular, Object-Oriented JavaScript framework designed for the intermediate to advanced JavaScript developer. It allows you to write powerful, flexible, and cross-browser code with its elegant, well documented, and coherent API.
Calling the javascript gurus out there.
Basically my question is regarding how you structure your code, both visually and for functionality for example do you wrap everything in objects using this structure:
var myapp={
binds:function(){
//put some event listeners for jquery etc...
},
otherfunc:function(){
//do some other thing
},
init:function(){
//call myapp.binds and other functions and other stuff to intialize your app.
}
};
Then finally
$(document).ready(myapp.init);
The thing is with a structure like this I think JSLint complains doesn't it? Whats the pros and cons using a structure like this or is there a generally better way to structure your code? Do you follow a certain pattern from $(document).ready(call) to putting all your event listeners and "initializing" your app, do you use separate objects for methods and variables?
I also think "visually" if you have a very large webapp this structure eventually looks very messy, but maybe it's just me I don't know, any input is appreciated thanks.
Using Inheritance Patterns to Organize Large jQuery Applications
explain in detail and with better practice by Alex
http://alexsexton.com/?p=51
its very very well explain, must see
other links
How To Manage Large jQuery Apps 5 months ago
It doesn't matter much how you structure your code as long as you follow the essentials rules of programming that your teacher thought you:
Don't write repetitive code
A function must do 1 and only 1 thing
Document your code
Some other small things but mostly the above... oh and apply lots of common sense
The only error you get from that is "implied global." You can get rid of the warning for document by using this.document instead (since window is the context). The implied global for $ will stay unless you paste in the jQuery source (then gl with all the errors in that).
I trust JSLint--a lot. On big projects I tend to make object literals as you did above but I use a module pattern for object security:
var myapp = (function () {
var secret_stuff, public_stuff;
return {
stuff: public_stuff
}
}());