get object data , load 2 condition the same time - javascript

var id = "displayImage1";
//my object
var json = {
displayImage1: {
object: "style1"
},
displayImage2: {
object: "style2"
},
displayImage3: {
object: "style3"
}
};
function JsonLoad(_id){
checkImgCanvas = _id;
for (var i in json) {
if(i === checkImgCanvas){
alert("yes got it");
}else{
alert("not object found");
}
}
}
i am using this function to check if any json object value match the id value , if yes load "yes got it" else load "not object found". i do get the match but it also load "not object found" 2 times , i have no idea why ? it should not load the else condition cause i have match in my json object.
how do i make this function if match load "yes" if no load else condition.(load once)
Demo

Since your for loop executes even after you found your result, you are getting the "no object found" message. You should exit your loop once you found your desired result and to achieve that, you can use break; after your success alert message
function JsonLoad(_id){
var matchFound = false;
for (var i in json) {
if(i === _id) {
matchFound = true;
break;
}
}
if(matchFound) {
alert("yes got it");
}else{
alert("not object found");
}
}

You can use Array.prototype.some()
The some() method tests whether some element in the array passes the test implemented by the provided function.
var json = { displayImage1: { object: "style1" }, displayImage2: { object: "style2" }, displayImage3: { object: "style3" } };
function JsonLoad(_id) {
!Object.keys(json).some(function (k) {
if (k === _id) {
document.write('yes got it<br>')
return true;
}
}) && document.write('not object found<br>');
}
JsonLoad('displayImage0');
JsonLoad('displayImage1');

Related

Why does chrome.storage.local save only the last record?

I am writing a Chrome extension in which I need to save data in chrome.storage.local. But, it saves only last record data. Can you explain me what am I doing wrong?
Ordinary localStorage is bad, because after resetting settings in the Chrome browser, localStorage is empty.
chrome.runtime.onMessage.addListener(function (request) {
if (request.type === 'setInLocalStorage') {
var key = request.key;
//alert(key);
chrome.storage.local.set({key: request.data},function () {
alert('data was saved');
});
}
return true;
});
chrome.runtime.onMessage.addListener(function (request, sender, SendResponse) {
if (request.type === 'getFromStorage') {
chrome.storage.local.get(null, function (items) {
var allKeys = Object.keys(items);
if (allKeys.length != 0) {
for (var i = 0; i < allKeys.length; i++) {
alert(items[allKeys[i]]);
if (items[allKeys[i]] === request.value) {
SendResponse(true);
} else if (i === allKeys.length - 1) {
SendResponse(false);
}
}
} else {
SendResponse(false);
}
});
}
return true;
});
Your problem is here:
var key = request.key;
//alert(key);
chrome.storage.local.set({key: request.data},function () {
alert('data was saved');
});
When you create an object using the notation {key: value}, the key is always "key", and not the value of any variable named key.
You can do it in the following way:
var data={};
data[request.key]=request.data;
chrome.storage.local.set(data,function () {
alert('data was saved');
});
Or, closer to your current code, using square brackets (in that position [] doesn't define an array, is the valid notation to define the key as the value of a given variable):
var key = request.key;
//alert(key);
chrome.storage.local.set({[key]: request.data},function () {
alert('data was saved');
});
Only the most recently saved value exists in storage.local, because you repeatedly store all values into the property 'key', which is overwritten each time you call chrome.storage.local.set(). Basically, you are not creating the Object you think you are for your call to chrome.storage.local.set().
You use the Object literal/Object initializer as:
{key: request.data}
This is equivalent to:
{'key': request.data}
It does not substitute in the value of the variable key. So, every time you attempt to save, you are storing the data in the property 'key', not the key which you are passing in the message (i.e. request.key).
You can use a computed property name directly within the Object initializer which you are already using:
{[key]: request.data}
This results in the contents of the variable key being used as the property to which to assign the value of request.data.
Which would make your code:
chrome.runtime.onMessage.addListener(function (request) {
if (request.type === 'setInLocalStorage') {
var key = request.key;
//alert(key);
chrome.storage.local.set({[key]: request.data},function () { //only this line changes
alert('data was saved');
});
}
return true;
});
Alternately, you can do the same thing, but a bit more verbose, by first creating the object and then setting the property:
chrome.runtime.onMessage.addListener(function (request) {
if (request.type === 'setInLocalStorage') {
var setObject = {};
setObject[request.key] = request.data;
//alert(key);
chrome.storage.local.set(setObject,function () {
alert('data was saved');
});
}
return true;
});

How to search in array

I have JavaScript array contains links something like this:
var urls = ['url1','url2','url3'];
if (urls.indexOf(window.location.hostname) > -1)
{
// do something ...
}
else {
window.location.href = 'redirect url';
}
this code work well, but I tried to convert it to an array of objects like this:
var urls = [
{
'url':'url1'
},
{
'url':'url2'
},
{
'url':'url3'
},
];
if (urls.url.indexOf(window.location.hostname) > -1)
{
// do something ...
}
else {
window.location.href = 'redirect url';
}
But this code is not working!!
How I can convert the first code into array of objects, or how I can search in array?
Easiest solution is to use array.some
if(urls.some(function(item) { return item.url == window.location.hostname;})) {
// do something ...
} else {
window.location.href = 'redirect url';
}
more readably
var found = urls.some(function(item) {
return item.url == window.location.hostname;
});
if(found) {
// do something ...
} else {
window.location.href = 'redirect url';
}
First of all: Both definitions of your urls variable are JSON:
first definition is an array of Strings in JSON notation
second definition is an array of objects, each consisting of one property url as a string.
In order to search through the second one, you need to iterate over the objects array explicitly and compare the property explicitly (as one approach):
var found = false;
for ( var n = 0; n < urls.length; n++ )
{
if ( urls[n].url == window.location.hostname )
{
/// do something
found = true;
break;
}
}
if ( !found )
{
// do something other
}
Or may be
if(urls.map(function(obj){ return obj.url}).indexOf(window.location.hostname)>0){
// do something ...
}
else {
window.location.href = 'redirect url';
}
Using lodash version 4 or later, you could do this:
if (_(urls).map('url').includes(window.location.hostname)) {
// do something...
} else {
window.location.href = 'redirect url';
}
When it comes to arrays of objects you cannot access elements like what you have done in your code. You have to use a loop to travers through the elements or an inbuilt functions like filter,map.Without using inbuilt functions you can do something like this to get your work done.
function to search for a particular url in the array
function findURL(array,url) {
for (var i = 0; i < array.length; i++) {
if (array[i].url == url) {
return i;
}
}
return -1;
}
Put below piece of code where you want to check the condition
var urls = [
{
'url':'url1'
},
{
'url':'url2'
},
];
if(findURL(urls,window.location.hostname) > -1){
//do something ..
}else{
window.location.href = 'redirect url';
}
There are some answers which describe how to apply filter and map methods in your scenario.Therefore I thing i don't want to put those in my answer.
If you use jquery there is a function called grep which returns an array of items found.
var urls = [
{
'url':'url1'
},
{
'url':'url2'
},
];
var result = $.grep(urls, function(e){ return e.url == window.location.hostname; });
if (result.length == 0) { // nothing found
window.location.href = 'redirect url';
} else if (result.length == 1) { // one item found
//do something ..
// you can access the found item by result[0].foo if you want
} else { // multiple items found
}

$.parseJSON(resp); if resp is number it works

I was using this to test if server returned data is json.
try {
json = $.parseJSON(resp);
} catch (error) {
json = null;
}
if (json) {
//
} else {
//
}
But it returns true if resp is a number lik 2 or 3 or... It returns null if resp is 0.
Any ideas how to avoid this false situation?
I'm outputting data using php:
echo 0; //returns null
echo 2; //returns as valid json
It appears, 0 is read as string, and 2 is read as number.
If you're expecting an integer, use parseInt:
try {
val = parseInt(resp, 10);
if(val > 0) /* act accordingly ... */
} catch (error) {
val = null;
}
If you want to know if the "JSON is valid," you can use something akin to the following:
function isValidJSON(string){
try {
$.parseJSON(string);
return true;
}
catch(e){ return false; }
}
I suggest something like:
// source from Angular source
function isJson(data) {
return (/^\s*[\[\{]/.test(data) && /[\}\]]\s*$/.test(data));
};
So...
if (isJson(resp))
json = $.parseJSON(resp);
else
alert ('another response: ' + resp);
Numbers like 2 or 3 are technically valid JSON data. Do you expect an object? See e.g. this SO post for methods of checking if the returned variable is an object.
Basically your workflow would be to try to parse it as JSON, and if it succeeds, check if it's an object/list (depending on what you expect).
Example:
try {
json = $.parseJSON(resp);
return (typeof(json) === "object")
} catch (error) {
json = null;
}

How to check if it's a string or json [duplicate]

This question already has answers here:
How to test if a string is JSON or not?
(22 answers)
Closed 3 years ago.
I have a json string that is converted from object by JSON.Stringify function.
I'd like to know if it's json string or just a regular string.
Is there any function like "isJson()" to check if it's json or not?
I'd like to use the function when I use local storage like the code below.
Thank you in advance!!
var Storage = function(){}
Storage.prototype = {
setStorage: function(key, data){
if(typeof data == 'object'){
data = JSON.stringify(data);
localStorage.setItem(key, data);
} else {
localStorage.setItem(key, data);
}
},
getStorage: function(key){
var data = localStorage.getItem(key);
if(isJson(data){ // is there any function to check if the argument is json or string?
data = JSON.parse(data);
return data;
} else {
return data;
}
}
}
var storage = new Storage();
storage.setStorage('test', {x:'x', y:'y'});
console.log(storage.getStorage('test'));
The "easy" way is to try parsing and return the unparsed string on failure:
var data = localStorage[key];
try {return JSON.parse(data);}
catch(e) {return data;}
you can easily make one using JSON.parse. When it receives a not valid JSON string it throws an exception.
function isJSON(data) {
var ret = true;
try {
JSON.parse(data);
}catch(e) {
ret = false;
}
return ret;
}
Found this in another post How do you know if an object is JSON in javascript?
function isJSON(data) {
var isJson = false
try {
// this works with JSON string and JSON object, not sure about others
var json = $.parseJSON(data);
isJson = typeof json === 'object' ;
} catch (ex) {
console.error('data is not JSON');
}
return isJson;
}
Since the question is "How to check if it's a string or json" maybe a simple way would be to check for string, so you would have done something like this somewhere:
if (typeof data === 'string') { // check for string!
//... do something
} else {///... do something else}
Maybe that could be enough depending on your overall solution, just in case someone else is looking around.
I think returning parsed JSON at the same time is a good idea, so I prefer following version:
function tryParse(str) {
try {
return { value: JSON.parse(str), isValid: true }
} catch (e) {
return { value: str, isValid: false }
}
}
As you probably know JSON.parse("1234"), JSON.parse("0"), JSON.parse("false") and JSON.parse("null") won't raise Exception and will return true. all this values are valid JSON but if you want to see isValid is true only for objects (e.g: { "key": "value" }) and arrays (e.g: [{ "key": "value" }]) you can use following version:
function tryParse(str) {
try {
var parsed = JSON.parse(str);
return { value: parsed , isValid: typeof parsed === 'object'}
} catch (e) {
return { value: str, isValid: false }
}
}

jquery function doesn't return values correctly

I have this function
$.fn.validate.checkValidationName = function(id) {
$.post("PHP/submitButtonName.php", {checkValidation: id},
function(data) {
if(data.returnValue === true) {
name = true;
} else {
name = false;
}
**console.log("name = "+name); **//this prints out "true"****
}, "json");
};
and this .click function that calls it. All the variables are declared outside this function so that they should be accessible by other functions
$('.submitBtn').click(function() {
//clears the array before re-submitting the click function
nameValues = [];
usernameValues = [];
emailValues = [];
name = false;
username = false;
email = false;
//for each of the input tags
$("input").each(function() {
//if the curent input tag has the class .name, .userpass, or .email
if(($(this).hasClass("name"))) {
nameValues.push($(this).val());
} else if(($(this).hasClass("userpass"))) {
usernameValues.push($(this).val());
} else if(($(this).hasClass("email"))) {
emailValues.push($(this).val());
}
});
//call the checkValidation function with the array "values"
$.fn.validate.checkValidationName(nameValues);
$.fn.validate.checkValidationUsername(usernameValues);
$.fn.validate.checkValidationEmail(emailValues);
console.log("name = "+name); //but this prints out "false"
console.log("username = "+username);
console.log("email = "+email);
if((name === "true") && (username === "true") && (email === "true")) {
alert("Everything checks out great");
} else {
alert("You missed one!");
}
});
When I click the link to trigger the first function, it returns the value as "true" inside the function, but when I console.log("name"+name); in the .click function after the function call, it prints out false.
Why is this? Do I need to return something from the checkValidatoinName function?
$.post is asynchronous, which means that it won't wait for the result to get back before proceeding. You're probably initializing name to true somewhere, and it's getting true the first time, but all the other times, it's false, because the AJAX from the first one finished and set it to false.
Try using $.ajax instead of $.post, and set async to false in the options. The $.post documentation shows the options that $.post would give to $.ajax.

Categories