how far should i validate user input in my own created API? - javascript

i got something here that bogs my mind a bit.
let's say i write me this API (in TS), check out some of these properties:
export class MyAPI{
propertyThatShouldContainSuffix:Array<string>; // like .jpg or .mp3
somethingElses:Array<SomethingElse>; //instances of some class
enumProperty:SomeEnum; // enum SomeEnum{a,b,c,d}
constructor(object){
/*
this object is input by the API consumer,
and its properties will be assigned to the new fields of
the new instance
*/
}
}
valid usage example:
var myApi = new MyAPI({
propertyThatShouldContainSuffix : ["img.jpg","video.mp4" ...],
somethingElses : [new SomethingElse(/*yada yada*/),new SomethingElse(/* whateverrr*/) ...],
enumProperty:2
});
input that may cause problems:
var myApi = new MyAPI({
propertyThatShouldContainSuffix : ["img","video",5 ...],
somethingElses : [new SomethingElse(/*yada yada*/),new SomethingTotallyElse(/* whateverrr*/) ...],
enumProperty:6
});
as you can see, the first property is an array of strings that need to have a suffix, like an image, that should be .jpg or .png or whatever. there is an array of objects that should contain some fields, and finally an enum field,
let's say that it ranges from 0 to 3.
now, it all works fine and stuff when you input the expected values into it
(e.g all strings in first array has the right suffix and so on)
but then i thought that i should handle bad input, like a user that
will send all his image names without any suffix, or will give me a "9" as
input for the enum, send objects instead of arrays, and so on.
BUT! and here's the problem: how far should i go with this?
should i check that every property is correct(e.g what is supposed to be an array is really an array, that all "supposed to be suffixed" are suffixed,
that all "somethingelses" contain all correct fields?
because if i do, this is a whole mess of overhead on every creation of an instance of MyAPI object.
or should i only do something real basic like check if he didn't misspell some field in the object(therefore exposing helpless users to the perils of "but why isn't this working?? stupid stupid API!!!") ?
or anything inbetween?
thank you!

Related

CSGO - How to display a users inventory from the JSON

I'm wanting to make a system that gets a users inventory then displays it as the image and name. I only know how to do the JSON part and I'm unsure as what to do next.
All I have at the moment is:
http://steamcommunity.com/profiles/<PROFILEID>/inventory/json/753/1
Is anyone able to help me turn that data into what I am looking for?
First off - for CS:GO, at least - the URL you are looking for is:
http://steamcommunity.com/profiles/<PROFILEID>/inventory/json/730/2
The two numbers at the end of the URL refer to the app ID and context ID, respectively. CS:GO's app ID is 730 and most games use a context ID of 2 for user inventories.
The JSON returned from this request is an object in the following format:
{
"success": true,
"rgInventory": { ... },
"rgCurrency": { ... },
"rgDescriptions": { ... },
"more": false,
"more_start": false
}
For the use-case you described (getting the item names and icons), you can ignore everything except the rgDescriptions object. This object contains an object for each item in the user's inventory. The object keys are the result of concatenating the item's classid and instanceid, but that doesn't really matter for you - you can just iterate over it like you would for any other object.
The two data points that you're interested in are market_hash_name, which is the name of the item, and icon_url, which is part of what you need to display the actual image. The full path to the image is https://steamcommunity-a.akamaihd.net/economy/image/{icon_url}. For example, this link loads the icon for a G3SG1 | Polar Camo in my inventory.
One thing to note is that the market_hash_name includes the wear pattern (e.g., Minimal Wear, Factory New, etc.). If you don't need those, you can just use the name from the object.

Avoiding duplicate JS object properties from a single assignment operation?

I am running a script on a large dataset to expand existing information. e.g:
...
{
id : 1234567890
},
{
id : 1234567891
},
...
becomes
...
{
id : 1234567890,
Name : "Joe"
},
{
id : 1234567891,
Name : "Bob"
},
...
I am doing this via the following code:
for(var cur in members)
{
curMember = members[cur];
// fetch account based on curMember.id to 'curAccount'
if(curAccount != null)
{
curMember.DisplayName = curAccount.DisplayName;
}
}
For the most part, this works as expected. However, once in a while (in the order of tens of thousands of entries), the result looks like this:
...
{
id : 1234567891,
Name : "Bob",
Name : "Bob"
},
...
I now have data which is in an invalid format and cannot be read by the DB, since duplicate property names doesn't make sense. It is occurring for random entries when the script is re-run, not the same ones every time. I need either a way to PREVENT this from happening, or to DETECT that it has happened so I can simply reprocess the entry. Anyone know what's going on here?
EDIT: After further investigation, the problem appears to occur only when the objects being modified come from a MongoDB query. It seems that if code explicitly sets a value to the same element name more than once, the field will be duplicated. All elements of the same name appear to be set to the most recently specified value. If it is only assigned once as in my original problem, it is only duplicated very rarely. I am using MongoDB 2.4.1.
Got it all figured out. MongoDB has a bug up to shell version 2.4.1 which allows duplicate element names to be set for query result objects. Version 2.4.3, released just this Monday, has a fix. See https://jira.mongodb.org/browse/SERVER-9066.
I don't really get your problem. If you apply identical property names to an object in ECMAscript, that property will just get overwritten. The construct in your snippet, can never be exist in that form on a live-object (excluding JSON strings).
If you just want to detect the attempt to create a property which is already there, you either need to have that object reference cached beforehand (so you can loop its keys) - or -
you need to apply ES5 strict mode.
"use strict";
at the top of your file or function. That will assure that your interpreter will throw an exception on the attempt to create two identical property keys. You can of course, use a try - catch statement to intercept that failure then.
Seems like you cannot intercept errors which get thrown because of strict mode violation.

validating JSON file in JavaScript

My Google Chrome extension uses JSON.parse(oldJSONstring) to create an object with configuration information. The "oldJSONstring" was saved from previous sessions on Chrome's localStorage.
As I sometimes add new features, after I create the new object, I manually validate that all configuration entries exist, if not, I'll set them with default values. This is done, in case it's he firs time a user loads the extension after it updated.
I was trying to think of a more automatic way of doing this, like using a JSON Schmea, but I really don't know where to start, and my first round of google searches didn't produce anything I could use.
Another approach I thought was to iterate on all my Default settings -also stored on a JSON object- and then confirming they exist on the new object... but I just realized I don't know how to iterate a JSON object for all its attributes :)
The end goal of this is that I'd like to forget about validating for new attributes, every time I create a new feature and I publish a new version... does it make any sense? does it make me lazy? :D
Thanks!
Keep the default object handy and use jQuery $.extend to merge the 2 objects.
var defaults={ color:'blue', size:'Large'}
var chromeObj= /* code to grab from storage*/
/* update chromeObj with all key/value pairs in defaults */
/* regardless if they already exist or not*/
$.extend( chromeObj, defaults}
/* code to put chromeObj back to storage*/
Refrence: http://api.jquery.com/jQuery.extend/
There is no such thing as a "JSON object,"* but it's quite easy to loop over a Javascript object's properties: How do I loop through or enumerate a JavaScript object?
* JSON is just a string format, and it's a subset of Javascript object notation

How to parse JSON dynamically in iOS

We used a third party service and it provides a JS file.
The js file launches an http request and get a json.We parsed the json and got the content we wanted but the json format always changes.
Is there a way to parse the json but do not update our app?
It sounds awful stupid to constantly change schemas, but anyway, maybe you could try having a manifest somewhere in the cloud that translates the latest schema keywords into one your app understands?
Basically, I presume that the info in the JSON is similar (otherwise it wouldn't make sense at all) and only the keywords change. You could have a JSON you constantly update that translates the keywords used in the app into the newest one used by the webservice.
So an example would look like this. Imagine this is the format you are used to when developing the app (this is the one app expects).
{
"name" : "Henri",
"title" : "iOS Developer"
}
Now if the webservice changes it's schema and returns something like this
{
"key1" : "Henri",
"key2" : "iOS Developer"
}
You should have a manifest.json which translates it like this
{
"name" : "key1",
"title" : "key2"
}
I hope you get where I'm going with this, basically you can shift the translation to the cloud, giving you the chance to keep it up to date while app remains the same. So after loading in the translation you can access the data like this
NSString *name = [actualJSON objectForKey: [manifestJSON objectForKey: #"name"]];
The JSON home page has quite a bit of materials on the subject which should allow you to develop your own parser if you wish. There are also some ObjectiveC parsers available down at the bottom of the page.
http://www.json.org/
For this purpose we looked at Cocoa's standard key path infrastructure but weren't particularly happy with how it combines with arrays and dictionaries. In the end I ended up writing my own little key-path lookup thing, essentially like:
- (id)objectAtPath:(NSString *)path inObject:(id)object
{
// accept an input string like key1.key2.key3.index.key4.etc;
// so we'll split on the dots and use each separate component
// to navigate the object graph
NSString *components = [path componentsSeparatedByString:#"."];
for(NSString *component in components)
{
if([object isKindOfClass:[NSDictionary class]])
{
// if this is a dictionary, use this component as
// a key into the dictionary
object = [object objectForKey:component];
}
else
if([object isKindOfClass:[NSArray class]])
{
// if this is an array, use this component
// as an index into the array
NSInteger index = [component integerValue];
// treat out of bounds indices as finding nil
// rather than raising an exception
if(index < 0 || index >= [object count]) object = nil;
else object = [object objectAtIndex:index];
}
}
}
So you might call objectAtPath:#"shoes.4.typeOfLaces" inObject:jsonResult if 'jsonResult' is a dictionary to get the array 'shoes', the dictionary at index 4 in the array and then whatever value that dictionary has for the key 'typeOfLaces'.
The production code actually has some smarter navigation aids, allowing you to say things like "take whichever object in this array of dictionaries has the largest value for the key 'size'" or "take the object with type=large if it exists, otherwise take any object", but exactly what you want to do there will depend on your app and the variability of the schema.
Once you're navigating object graphs by key path, you can just grab the current key paths from a server somewhere, allowing you to change how JSON is navigated on device without submitting a new binary.
The only warning I'd add is to be careful how much functionality you put into your key paths. Apple don't allow fresh code to be downloaded so whatever you do you don't want to end up at anything that Apple could construe as a scripting language, no matter how restricted.

properties of object variables how to target them

What I'm given in my homework is and JS object that looks like:
myObj =
{name:eric, location:belgium, age:24},
{name:jools, location:holland, age26},
{name:mike, location:usa, age:30},
the idea is that somehow if i need to target 'location' holland i need to be able to treat all this like an arary so I can work with indexes (at least that's what I think). I Can't find any example anywhere where people work with this been searching for a bit on 'js object'.
The actual challenge is to be able to put the different values of the 'name' property as innerHTML(or some method that does something similar) of new option elements inside a given select element probably through a loop. Since this is homework, I don't need the actual code for that but a clue on where I can learn more about how these JS object property array type of things work would be nice.
thanks a lot!
Your JavaScript snippet is invalid, something makes me think there was a copy-and-paste error. The answer changes significantly depending on what the code actually looks like.
If it looks like this:
myObj = [
{name:eric, location:belgium, age:24},
{name:jools, location:holland, age26},
{name:mike, location:usa, age:30},
// ...
];
...then you're dealing with an array of objects, where each object has the properties name and location. You can loop through them using a standard for loop with an index variable, counting from 0 to myObj.length - 1 (inclusive), and access the properties of each object via myObj[index].name and myObj[index].location.

Categories

Resources