How can I tell 'Whether a Javascript object exists on my page'? - javascript

I can't get the the conditional to work in this function, any help?
function headupdate(id, name, heading)
{
var order;
if (document.getElementById(heading).value === undefined)
{
order = 1;
}
else
{
order = document.getElementById(heading).value;
}
alert(order);
$.post('headingupdate.php', {id: id, name: name, value: heading, order: order},
function(response)
{
$('#resume').html(response)
}
)
};

You should check as following.
var head = document.getElementById(heading);
if(head!=null)
{
order = head.value;
}
else
{
order=1;
}

In response to your post title, I use typeof() to find if an element exists in the DOM:
if(typeof(document.getElementById('someElement')=='undefined')) {
alert('Element DNE');
}
Also, typeof() returns a string, so it needs to be in quotes for a conditional statement
"undefined"

Related

How to skip or pass a parameter into a child node in JSON object declaration in javascript

Sorry for being a noob on JSON. I have a parameter I want to pass into calling the JSON object.
JSON:
{
"environments":{
"test":{
"on":true
}
}
}
On the above, the 2nd node test is dynamic depending on the environment you are at. I would like pass a parameter value so that key can change based on your declaration (no arrays used above and this is a third-party API that I cannot change).
Code:
const envName = 'test' // This can be changed to 'uat' too
if(body.environments.test.on === true) //I need the 'test' to change or parameterised.
{
// Do something
}
Basically, I would like to skip the key 'test' or pass the value from envName. I included a wildcard * and it did not work.
You can use square brackets to parameterize the environment:
let body = {
"environments":{
"uat":{
"on":true
}
}
}
const envName = 'uat';
if(body.environments[envName].on === true)
{
console.log('true');
}
or Object.values() to do the wildcard scenario:
let body = {
"environments":{
"uat":{
"on":true
}
}
}
const envName = 'uat';
if(Object.values(body.environments).some(x => x.on === true))
{
console.log('true');
}
You can use a for .. in loop to go through the nested elements of body.environments and check if on is true or not like this:
const body = {
"environments":{
"test":{
"on":true
}
}
}
for(let b in body.environments) {
if(body.environments[b].on) {
console.log(body.environments[b].on);
}
}

Checking for empty data in JSON in JavaScript

I'm working with an API call that's returning JSON and in some scenarios some of the data is empty. For example, the snippet below shows that roleBusinessScopes is empty.
{
"userProfile": {
"organizationContacts": [
{
"roleBusinessScopes": {}
}
]
}
}
I wanted to be able to check if roleBusinessScopes is empty. I tried roleBusinessScopes.length = 0, however, that doesn't work.
When roleBusinessScopes does return data...
"roleBusinessScopes": {
"businessScopes": {
"scopeName": "something"
}
}
... I can check for that:
if (organizationContacts[i].roleBusinessScopes.businessScopes[0].scopeName !== "something")
{
// do something
}
How can I check if roleBusinessScopes has no data?
You can use Object.keys(obj).length > 0 to check if object has some keys (data) or not
if (Object.keys(organizationContacts[i].roleBusinessScopes).length > 0) {
// Not empty
} else {
// empty
}
Assuming the structure is always the same (and that you're in a ideal world where you don't need to check the validity of each property and child object), you could just check if businessScopes is not undefined.
let objectWithoutRoleBusinessScopes = {
"userProfile": {
"organizationContacts": [{
"roleBusinessScopes": {}
}]
}
};
let objectWithRoleBusinessScopes = {
"userProfile": {
"organizationContacts": [{
"roleBusinessScopes": {
"businessScopes": {
"scopeName": "something"
}
}
}]
}
};
function hasRoleBusinessScopes(objectToTest) {
return objectToTest.userProfile.organizationContacts[0].roleBusinessScopes.businessScopes != undefined;
}
console.log(hasRoleBusinessScopes(objectWithoutRoleBusinessScopes));
console.log(hasRoleBusinessScopes(objectWithRoleBusinessScopes));
You could try using Object.keys({your_object_here...}) and check the length of the returned array.
You should be able to do something like
if (Object.entries(organizationContacts[i].roleBusinessScopes).length === 0) {
// do something
}
Object.entries() will return a list of all the object's properties, which you can use to key in on length.
You could simply check if it is empty or not by this statement
if(organizationContacts[i].roleBusinessScopes === {}){
// handle empty case here
} else {
// handle non-empty case here
}
What I would use is a function to check it as there are multiple possibilities .
Sometimes a server will write null in its place so alternative checks need to be made
Us this function
function checkempty(jsonString) {
if (jsonString == null ||
jsonString == undefined ||
jsonString.length == 0) {
console.log("Name cannot be empty\n");
return false;
} else {
console.log("Your response has been recorded\n");
return true;
}
}
checkempty(Object.keys(organizationContacts[i].roleBusinessScopes))

JavaScript find property in JSON object

I have a JSON object that looks a bit like this:
{
name: 'test',
details: {
description: 'This is the long description',
shortDescription: 'This is the short description (ironically longer than the description!)'
}
}
Obviously the real object is a lot more complicated than this example, but I have omitted the details because they will only complicate the question.
So, with this object, I have a function that tries to get the value of the property, it looks like this:
// Private function for matching fields
var _matchField = function (item, filter) {
// Our variables
var text = item[filter.field],
values = filter.expression.split(',');
// If we have any text
if (text) {
// Loop through our values
angular.forEach(values, function (value) {
console.log(text);
console.log(value);
// See if we have a match
if (text.toLowerCase().indexOf(value.toLowerCase()) > -1) {
// We have found a match
return true;
}
});
}
// We have found no matches
return false;
}
The issue is the line:
var text = item[filter.field],
If the property was just the name then item['name'] would work with the above object. But if I want to get the description; item['details.descrption'] doesn't work.
So I need a function that will allow me to specify a property name and it will find the property and return its value.
But before I try to write one, I was hoping there might be a simple solution that someone has come across.
you can write your custom function for this
function getProperty(json, field) {
if (json == null || field == null) {
return null;
}
var value = json;
var fields = field.split(".");
for (var i = 0; i < fields.length; i++) {
value = value[fields[i]];
if (value == null) {
return null;
}
}
return value;
}
check this plnkr example https://plnkr.co/edit/8Ayd9wnh1rJh1ycx5R1f?p=preview
You can split the reference to the object and use a function for getting the right nested object/value.
function getValue(o, p) {
if (typeof p === 'string') {
p = p.split('.')
}
return p.length ? getValue(o[p.shift()], p) : o;
}
var item = { name: 'test', details: { description: 'This is the long description', shortDescription: 'This is the short description (ironically longer than the description!)' } };
document.write(getValue(item, 'details.description'));
I solved this by creating this function:
// Private function to get the value of the property
var _getPropertyValue = function (object, notation) {
// Get all the properties
var properties = notation.split('.');
// If we only have one property
if (properties.length === 1) {
// Return our value
return object[properties];
}
// Loop through our properties
for (var property in object) {
// Make sure we are a property
if (object.hasOwnProperty(property)) {
// If we our property name is the same as our first property
if (property === properties[0]) {
// Remove the first item from our properties
properties.splice(0, 1);
// Create our new dot notation
var dotNotation = properties.join('.');
// Find the value of the new dot notation
return _getPropertyValue(object[property], dotNotation);
}
}
}
};

Push element into JSON object

I want to go through a JSON, if a certain condition applies then push some extra elements in that index.
I have this JS code:
$scope.addRoleToUser = function() {
var userid = $scope.selectedUser;
var tmpdata = [];
var index = 0;
//alert(userid);
angular.forEach($scope.users, function(data) {
if (data.id == $scope.selectedUser) {
tmpdata.push(data,{"roles":[{"id":"00","name":"newrole"}]});
}
else {
tmpdata.push(data);
}
index++;
});
$scope.users = tmpdata;
};
This is my initial JSON element:
$scope.users = [
{"id":"0","name":"User1","roles":[{}]},
{"id":"1","name":"User2","roles":[{}]},
]
I'm trying to get it to look like this after the function runs:
$scope.users = [
{"id":"0","name":"User1","roles":[{"id":"00","name":"newrole"}]},
{"id":"1","name":"User2","roles":[{}]},
]
But instead I'm getting this:
[{"id":"0","name":"User1","roles":[{}]},{"roles":[{"id":"00","name":"newrole"}]},{"id":"1","name":"User2","roles":[{}]}]
Just replace this inside your function
if (data.id == $scope.selectedUser) {
data.roles = [{"id":"00","name":"newrole"}];
}
Or, if you know that roles is not empty, you can do:
if (data.id == $scope.selectedUser) {
data.roles.push({"id":"00","name":"newrole"});
}
And after this line you can add your data to tmpdata!
That snippet now will look like this:
if (data.id == $scope.selectedUser) {
data.roles = [{"id":"00","name":"newrole"}]}); //or the other one
}
tmpdata.push(data);
Inside the forEach() callback you're just working with objects and as such, you can modify them directly inside the callback:
angular.forEach($scope.users, function(data) {
if (data.id == $scope.selectedUser) {
data.roles = [{"id":"00","name":"newrole"}];
}
});
Similarly you could modify almost anything of each entry by manipulating the respective data object.
Example Fiddle
The Array.prototype.push method is variadic: (https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/push).
When you call tmpdata.push(a,b,c), you are in essence appending the array [a,b,c] to tmpdata.
You can also decompose the problem with something like:
$scope.addRoleToUser = function() {
var thisUserid = $scope.selectedUser;
function addRolesFor(user) {
if (user.id === thisUserId){ user.roles = [{"id":"00","name":"newrole"}] };
return user;
}
retrun $scope.users.map(addRoles);
}
Please use the map function that is appropriate for your environment (like _.map), because the Array.prototype.map method is not supported by all browsers.

In JavaScript given an object property value, can I find a corresponding property name?

I'm passing a config object with names for each slide to a function that instantiates a jQuery tools scrollable. I want the URL in the location bar to match the active tab id. I have it working so that passing the URL with the name in will navigate to the correct slide (that's at the bottom of the provided code), but I'm trying to get the URL updating when the slide changes. I know what I need to do to get that, but not how to do that, which is like in the question title.. pass a value to an object and get a property that has that value.
$(function () {
Scrollablenav.init({
"#tulips": 0,
"#daffodils": 1,
"#zebras": 2,
"#horseshoes": 3
});
});
Scrollablenav.init = function(config){
var scroller = $(".scrollable").scrollable({
circular: true,
onSeek: function (event) {
parent.location.hash = function(){
//something that looks at config, sends it the value of the current slide and returns corresponding property name
}
}
}).navigator({
navi: '#slideTabs',
naviItem: 'a',
activeClass: 'current',
history: true
}).data('scrollable');
if (!isNaN(config[location.hash])){
scroller.seekTo(config[location.hash], 0);
}
}
You can create your own function to find property name based on its value:
function findPropertyName(object, property_value, strict) {
if (typeof strict=='undefined'){
strict = false;
};
for (property in object){
if ((strict && object[property] === property_value) ||
(!strict && object[property] == property_value)){
return property;
}
}
return false;
}
Function description:
It will return name of the first property having given value, or false if no such property has been found.
Third param is responsible for determining whether strict comparison should be made (eg. string "123" is equal to integer 123 - like in '123'==123, but not strictly equal - like in '123'===123).
Function could be improved to return all the properties having given value, but I think you do not need it.
To check the function in action see this jsfiddle.
Something like this?
function getMyHash(config, value) {
for (item in config) {
if (config[item] === value) {
return item;
}
}
};
basically you have to iterate and match values; you can't lookup by value.
Can you change the format of your config? In other words, can we do:
$(function () {
Scrollablenav.init({
"#tulips": { Key: 'tulips', Index: 0 },
"#daffodils": { Key: 'daffodils', Index: 1 },
"#zebras": { Key: 'zebras', Index: 2 },
"#horseshoes": { Key: 'horseshoes', Index: 3 }
});
});
If that doesn't work, you can make a new object somewhere that maps the indexes back to the key:
var keys = {
1: 'tulips',
2: 'daffodils',
3: 'zebras',
4: 'horseshoes',
};
UPDATE:
You could also build this config dynamically:
$(function () {
var values = ['#tulips', '#daffodils', '#zebras', '#horseshoes'];
var config = {};
for(var i = 0; i < values.length; i++)
{
config[values[i]] = { Index: i, Key: values[i] };
}
Scrollablenav.init(config);
});

Categories