Chrome removes property value - javascript

I think I've run into a possible bug in chrome, but wondering if this is something I'm doing wrong. I am collecting data from an IndexedDb and adding this to an array BUT one property was always empty so I started debugging.
Below is my code for the onsuccess function and below that is a print screen of one of the rows from my console.log with one property marked with yellow. Notice how this exists and has a value!
On my second image which is when I "open" the object in chrome developer tools to see how it looks, I noticed that Title is undefined. What am I missing? What causes this behavior?
This exact code is working on the same site, just another page.
cursorRequest.onsuccess = function (evt) {
var cursor = evt.target.result;
if (cursor) {
var pushItem = true;
if (opts.searchCriterias && opts.searchCriterias.length > 0) {
pushItem = false;
for (var i = 0; i < opts.searchCriterias.length; i++) {
if (opts.searchCriterias[i].values.contains(cursor.key)) {
if (opts.includeKeyInResponse == true) items.push({ key: cursor.primaryKey, value: cursor.value });
else items.push(cursor.value);
}
}
}
if (pushItem) {
if (opts.includeKeyInResponse == true) items.push({ key: cursor.primaryKey, value: cursor.value });
else {
items.push(cursor.value);
}
console.log(cursor.value);
}
cursor.continue();
}
};
Title exists and have value
Title exists but is undefined (This is same as above, just expanded)

Related

IF statement to identify 'null' in loop being ignored

I have the following loop which I have put together and is working (up to a point):
for (var i = 0; i < dataIn.length; i++) {
if (dataIn.YourName = [] ) {
var modifiedName = dataIn[i].YourName.replace(/ \([\s\S]*?\)/g, '');
dataIn[i].YourName = modifiedName;
}
else {
console.log('Do Nothing');
}
}
However, I run into an error when the content from the API source is empty (null).
Console error: Cannot read property 'replace' of null
As a result I have tried to update my loop to only run if the information is NOT null or undefined (see below), but it is being ignored and still trying to run.
for (var i = 0; i < dataIn.length; i++) {
if (dataIn.YourName !== null && dataIn.YourName !== '' ) {
var modifiedName = dataIn[i].YourName.replace(/ \([\s\S]*?\)/g, '');
dataIn[i].YourName = modifiedName;
}
else {
console.log('Do Nothing');
}
}
Sample data from the API.
What works:
"YourName": "John Citizen",
What throws the console error:
"YourName": null,
Let's first address an issue here. This line:
if (dataIn.YourName = [] ) {
Will always evaluate true. You are assigning an empty array to your YourName property and then using that assignment in an if - empty arrays are always truthy.
As to how you've tried to correct it, you're checking initially dataIn.YourName but then trying to read dataIn[i].YourName - you need to be consistent. I suspect what you want is:
if (dataIn[i].YourName !== null && dataIn[i].YourName !== '' ) {
var modifiedName = dataIn[i].YourName.replace(/ \([\s\S]*?\)/g, '');
dataIn[i].YourName = modifiedName;
}

How do I use data out of chrome.storage.get function?

I'm trying to grab data from chrome extension storage, but I can use them only in this function.
var help = new Array();
chrome.storage.local.get(null, function(storage){
//get data from extension storage
help = storage;
console.log(storage);
});
console.log(help); // empty
Result in console:
content.js:1 content script running
content.js:11 []
content.js:8 {/in/%E5%BF%97%E9%B9%8F-%E6%99%8F-013799151/: "link", /in/adam-
isaacs-690506ab/: "link", /in/alex-campbell-brown-832a09a0/: "link",
/in/alex-davies-41513a90/: "link", /in/alex-dunne-688a71a8/: "link", …}
Async function has won. I wrote my code again and now function is called hundreds time, i can not do this in dirrefent way
code:
console.log("content script running");
var cards = document.getElementsByClassName("org-alumni-profile-card");
var searchText = "Connect";
function check(exi, cards) {
chrome.storage.local.get(null, function(storage) {
for (var key in storage) {
if (storage[key] == "link" && key == exi) {
cards.style.opacity = "0.3";
}
}
});
}
for (var i = 0; i < cards.length; i++) {
var ctd = cards[i].getElementsByClassName(
"org-alumni-profile-card__link-text"
);
var msg = cards[i].getElementsByClassName(
"org-alumni-profile-card__messaging-button-shrunk"
);
if (ctd.length < 1 || msg.length > 0) {
cards[i].style.display = "none";
} else {
var exi = cards[i]
.getElementsByClassName("org-alumni-profile-card__full-name-link")[0]
.getAttribute("href");
check(exi, cards[i]);
}
}
SOLUTION of my problem
I wanted to delete this topic, but I can not, so instead of doing that, I'll put here what I've done finally.
The code above is wrong becouse, it was taking a list of links from website and for each from them script was grabbing a data from a storage... Which was stupid of course. I didn't see a solution which was so easy:
Put all your file's code in this function - it grabs data from storage just once.
I'm so sorry for messing up this wonderfull forum with topic like this.
Hope u'll forgive.
help will return undefined because it is referencing a asynchronous function and not the return value of that function. The content from storage looks to be printed on content.js:8, i.e. line 8.

Debugging a background script in a Chrome extension

I'm trying to use some code from an open source library and I'm having some trouble logging to check where the code is failing.
In background.js:
chrome.extension.onRequest.addListener(function(request, sender, response) {
// This does not show in my console
console.log("request here");
switch(request.type) {
case 'enable?':
objectName.onTabSelect(sender.tab.id);
break;
case 'search':
// Also does not log here
console.log("Gets to first search item");
var e = objectName.search(request.text);
response(e);
break;
case 'open':
....
}
In content.js:
//This shows in my console
console.log("CHAR");
console.log(char);
document.body.innerText.match(/[\u3400-\u9FBF]/g).forEach(function (char) {
chrome.extension.sendRequest({
"type": "search",
"text": char
},
function (char_return) {
//This shows in my console, but is an empty obj and why I want to debug
console.log("char return");
console.log(char_return);
});
});
In main.js, a background script:
var objectName = {
...
search: function(text) {
// Does not log here. This is the area I REALLY want to log.
console.log("Char search gets here");
var entry = this.dict.wordSearch(text);
if (entry != null) {
for (var i = 0; i < entry.data.length; i++) {
var word = entry.data[i][1];
if (this.dict.hasKeyword(word) && (entry.matchLen == word.length)) {
// the final index should be the last one with the maximum length
entry.grammar = { keyword: word, index: i };
}
}
}
return entry;
}
}
How do I log in a background script? It looks like maybe I should be using the chrome.webRequest method? Could this be because some of the methods are deprecated? I intend on updating them to the new methods once I've got the application working, but to get it working I need to log and see where it is failing.
This is the first Chrome extension I've built so I'm not quite sure how this works.

Is this the correct way to express no value in this function?

I have a accordion which has been set up to open to a specific panel by appending this string to the URL?panel=0
farfegnugen = jQuery.noConflict();
farfegnugen(document).ready(function($) {
var defaultPanel = parseInt(getParam('panel'));
farfegnugen("#st-accordion").accordion({
open: defaultPanel
});
function getParam(name) {
var query = location.search.substring(1);
if (query.length) {
var parts = query.split('&');
for (var i = 0; i < parts.length; i++) {
var pos = parts[i].indexOf('=');
if (parts[i].substring(0, pos) == name) {
return parts[i].substring(pos + 1);
}
}
} else if(query.length === undefined){
window.location.href = "#topOfPage";
}
return false;
}
});
However, I have noticed it scrolls slightly to the body of the accordion on load despite not having selected a specific panel. To fix this behavior I figured adding this else if block would check to see if the parameter was empty, if so we would force the window to scroll where that anchor is situated.
<a id="topOfPage" href='#'></a>
So wouldn't else if(query.length === undefined) work because you're saying nothing, is there?
P.S. I tried null too, and that didn't work!
Try running location.search.substring(1).length in your console and you will see what the issue is. It is equal to 0 which is not undefined. In your case, you don't need an else if, you can simply use an else

ComboBox typeAhead works but valueField is null under certain behavioral conditions

Requesting a sanity check here please...
ExtJS 4.2 comboBox Typeahead works but having issues retrieving the valueField under the following conditions:-
1) If a user types a value and then instead of hitting enter or clicking on the select combo list, they click elsewhere then the valueField is empty but the selected value is present.
2) Assuming that the combobox item was selected correctly, If I enter an additional character and then backspace that character, the combo box can no longer find the valueField..its almost like it has reset itself.
Fiddle example
https://fiddle.sencha.com/#fiddle/je1
How to reproduce
If you enter Maggie in the combo box, you will see the valueField ID in the console window, if you append a character and then backspace the character, the ID in the console window is null
(You will need to open the console window to see the output)
forceSelection does not resolve this issue as I have a template and it will not accept an entry in the combobox that is not part of the store, and I need to use sumID for my valueField as I need to retrieve and pass that value to the server.
Thank you everyone, awesome to have such a great community!!
I was able to get around this by using forceSelection and overriding the setValue thus allowing template items not in the store but in the combo to be selected via forceSelection. From playing around with the combobox, IMO, for a good look and feel, forceSelection is the way to go.
Here is my override, refer to statement //start of override
This was a quick fix, I will refine statement when I am back in the office, below I am pasting the solution from memory, you get the idea.
setValue: function(value, doSelect) {
var me = this,
valueNotFoundText = me.valueNotFoundText,
inputEl = me.inputEl,
i, len, record,
dataObj,
matchedRecords = [],
displayTplData = [],
processedValue = [];
if (me.store.loading) {
// Called while the Store is loading. Ensure it is processed by the onLoad method.
me.value = value;
me.setHiddenValue(me.value);
return me;
}
// This method processes multi-values, so ensure value is an array.
value = Ext.Array.from(value);
// Loop through values, matching each from the Store, and collecting matched records
for (i = 0, len = value.length; i < len; i++) {
record = value[i];
if (!record || !record.isModel) {
record = me.findRecordByValue(record);
}
// record found, select it.
if (record) {
matchedRecords.push(record);
displayTplData.push(record.data);
processedValue.push(record.get(me.valueField));
}
// record was not found, this could happen because
// store is not loaded or they set a value not in the store
else {
//start of override
// 'Select All Names' is the template item that was added // to the combo box, it looks like an entry from the store
// but it is not in the store
if (me.forceSelection && me.getDisplayValue() === 'Select All Names'){
processedValue.push(value[i]);
dataObj = {};
dataObj[me.displayField] = value[i];
displayTplData.push(dataObj);
}
//end of override
if (!me.forceSelection) {
processedValue.push(value[i]);
dataObj = {};
dataObj[me.displayField] = value[i];
displayTplData.push(dataObj);
// TODO: Add config to create new records on selection of a value that has no match in the Store
}
// Else, if valueNotFoundText is defined, display it, otherwise display nothing for this value
else if (Ext.isDefined(valueNotFoundText)) {
displayTplData.push(valueNotFoundText);
}
}
}
// Set the value of this field. If we are multiselecting, then that is an array.
me.setHiddenValue(processedValue);
me.value = me.multiSelect ? processedValue : processedValue[0];
if (!Ext.isDefined(me.value)) {
me.value = null;
}
me.displayTplData = displayTplData; //store for getDisplayValue method
me.lastSelection = me.valueModels = matchedRecords;
if (inputEl && me.emptyText && !Ext.isEmpty(value)) {
inputEl.removeCls(me.emptyCls);
}
// Calculate raw value from the collection of Model data
me.setRawValue(me.getDisplayValue());
me.checkChange();
if (doSelect !== false) {
me.syncSelection();
}
me.applyEmptyText();
return me;
},
Look at the sources of Combobox and try override this method as follows
doLocalQuery: function(queryPlan) {
var me = this,
queryString = queryPlan.query;
if (!me.queryFilter) {
me.queryFilter = new Ext.util.Filter({
id: me.id + '-query-filter',
anyMatch: me.anyMatch,
caseSensitive: me.caseSensitive,
root: 'data',
property: me.displayField
});
me.store.addFilter(me.queryFilter, false);
}
if (queryString || !queryPlan.forceAll) {
me.queryFilter.disabled = false;
me.queryFilter.setValue(me.enableRegEx ? new RegExp(queryString) : queryString);
}
else {
me.queryFilter.disabled = true;
}
me.store.filter();
if (me.store.getCount()) {
if (me.rawValue === me.lastSelection[0].get(me.displayField)){
me.setValue(me.lastSelection);
} else {
if(me.store.getCount() === 1){
me.setValue(me.store.first());
}
me.expand();
}
} else {
me.collapse();
}
me.afterQuery(queryPlan);
},

Categories

Resources