I am trying to render markers on the map dynamically with the end goal of markers being able to be created and destroyed at will while the application is running. Everything is working fine, except for one small section which is this:
for (j = 0; j < markersArray.length; j ++) {
console.log("Data: J=" + j + ", " + markersArray[j].key + ", " + markersArray[j].location[0] + ", " + markersArray[j].location[1] + ", " + markersArray[j].contactName);
return <MapView.Marker
key = { markersArray[j].key }
coordinate = {{
latitude: markersArray[j].location[0],
longitude: markersArray[j].location[1]
}}
title = { markersArray[j].contactName }
/>
}
The problem here is that the array has two or more objects inside it, but will only ever go through the loop once, where j = 0. It never goes through the loop another time. My thoughts are because the word "return" is used so that I can render the marker. Is there a way around this? All the data is perfect, it simply won't loop through more than the first time.
For the pedants among you who want the whole render function ;) :
render() {
return (
<MapContainer>
<MapView
style = { styles.map }
region = { this.state.mapRegion }
showsUserLocation = { true }
followUserLocation = { true }
onRegionChangeComplete = { this.onRegionChangeComplete.bind(this) }>
<MapView.Circle
key = { (this.state.currentLongitude + this.state.currentLongitude).toString() }
center = { userPosition }
radius = { RADIUS }
strokeWidth = { 1 }
strokeColor = { '#ffffff' }
fillColor = { 'rgba(210,218,215,0.5)' }
onRegionChangeComplete = { this.onRegionChangeComplete.bind(this) }
/>
{(() => {
console.log("Map Markers polling for data...");
if (markersArray[0] != null) {
console.log("Map Markers have found data");
for (j = 0; j < markersArray.length; j ++) {
console.log("Data: J=" + j + ", " + markersArray[j].key + ", " + markersArray[j].location[0] + ", " + markersArray[j].location[1] + ", " + markersArray[j].contactName);
return <MapView.Marker
key = { markersArray[j].key }
coordinate = {{
latitude: markersArray[j].location[0],
longitude: markersArray[j].location[1]
}}
title = { markersArray[j].contactName }
/>
}
}
})()}
</MapView>
<MessageBar />
</MapContainer>
)
}
I believe that you need map function in order to render every object in that array.
The map() method creates a new array with the results of calling a provided function on every element in the calling array.
{markersArray[0] != null && markersArray.map((marker, index) => (
<MapView.Marker
key = {index}
coordinate = {{
latitude: marker.location[0],
longitude: marker.location[1]
}}
title = { marker.contactName }
/>
))
}
Related
fileName = inputParam.file_name.split('.')[0].toLowerCase().replace(/ /g, '') + '' + Date.now() + "." + (fileData.file.name.split('.')[1] || inputParam.file_name.split('.')[1])
filePath = filePath + fileName
This is the condition I am using.
For example it should only restrict a.jpeg.jpg or a.php.jpeg. and allow extension like a.a.jpeg or bird.tree.jpeg
var _validFilejpeg = [".jpeg", ".jpg", ".bmp", ".png",".pdf", ".txt"];
var invalid = [".php",".php5", ".pht", ".phtml", ".shtml", ".asa", ".cer", ".asax", ".swf",".xap"];
function validateForSize(oInput, minSize, maxSizejpeg) {
//if there is a need of specifying any other type, just add that particular type in var _validFilejpeg
if (oInput.type == "file") {
var sFileName = oInput.value;
var file = sFileName.match(/\d/g);
var fileExt = sFileName.substr(sFileName.length-4);
if (sFileName.length > 0) {
var blnValid = false;
for (var j = 0; j < _validFilejpeg.length; j++) {
var sCurExtension = _validFilejpeg[j];
if (sFileName.substr(sFileName.length - sCurExtension.length, sCurExtension.length)
.toLowerCase() == sCurExtension.toLowerCase()) {
blnValid = true;
break;
}
}
if(fileExt = 'invalid'){
alert("Your document does not have a proper file extension.")
blnValid = false;
}
if(fileExt = 'file'){
alert("Your document does not have a proper file extension.")
blnValid = false;
}
if (!blnValid) {
alert("Sorry, this file is invalid, allowed extension is: " + _validFilejpeg.join(", "));
oInput.value = "";
return false;
}
}
}
fileSizeValidatejpeg(oInput, minSize, maxSizejpeg);
}
function fileSizeValidatejpeg(fdata, minSize, maxSizejpeg) {
if (fdata.files && fdata.files[0]) {
var fsize = fdata.files[0].size /1024; //The files property of an input element returns a FileList. fdata is an input element,fdata.files[0] returns a File object at the index 0.
//alert(fsize)
if (fsize > maxSizejpeg || fsize < minSize) {
alert('This file size is: ' + fsize.toFixed(2) +
"KB. Files should be in " + (minSize) + " to " + (maxSizejpeg) + " KB ");
fdata.value = ""; //so that the file name is not displayed on the side of the choose file button
return false;
} else {
console.log("");
}
}
}
<input type="file" onchange="validateForSize(this,20,5000);" >
You can simply do this
if (fileName.split('.').length > 2) {
throw new Error('Double extension file detected')
}
I have 13 images shown in page ,one of them is fixed and others changed depend on some data ,i made 12 if statement and it works ,but is there way to create one if statement with for loop like thus :
for (int i = 2; i >= 13; i++)
{
if (m_id >= i)
{
"image" + i.Source = ImageSource.FromFile("months" + i + ".png");
}
else
{
"image" + i.Source = ImageSource.FromFile("months"+i+"closed.png");
}
}
You should put all Images in an Array like
List<Image> Images = new List<Image>() {image2,image3,...,image13 };
And set the ImageSource like
for(int i=2;i<=13;i++)
{
Image image = Images[i - 2];
if (m_id >= i)
{
image.Source = ImageSource.FromFile("months" + i + ".png");
}
else
{
image.Source = ImageSource.FromFile("months"+i+"closed.png");
}
}
I have below functions that I am trying to use an async function to check if an item Id was already added into a grid. But, I am stuck at the for loop "processFindCode" function, it always returns false. How to make the checking routine work and continue to addItem function?
My objective,
1. a loop up event pass in selected array values
2. get needed info array via web api
3. process each of array item
4. validate if the item.Id_item_code already exists in detail grid, if not add a new item into the grid
sorry for the lengthy code, I am considered new to js. please also advise the best way to achieve my objective.
Thank in advance
var theList = this.value;
if (theList == "") {
return true;
}
// Set up aysnc promise function
async function processAPIResult() {
let result;
let promises = []; //setup a promises aray
// Loop thru Lookup selections
// results store in the promises aray
theList.split(',').forEach(function (kId, k) {
promises.push(make_api_call(kId));
})
result = await Promise.all(promises); // async await
return result;
}
// Call API Function
function make_api_call(id) {
return ($.get(ew.API_URL + "GetQuotationDetail/" + encodeURIComponent(id)));
}
function delay() {
return new Promise(resolve => setTimeout(resolve, 300));
}
async function addItem(kcode) {
var ridx = $("#key_count_fs_invoicedtlgrid")[0].value; // get actual table row
// Get serices information from API
var tQty = 1;
if (ridx == 1 && $("#x1_Id_item_code")[0].value == "") {
$("#x" + ridx + "_Id_item_code").value(kcode);
$("#x" + ridx + "_qty").value(tQty);
$("#x" + ridx + "_Id_item_code").select();
$("#x" + ridx + "_Id_item_code").change();
//$("#x" + ridx + "_Id_quotattoindetl").value(Id_quotationDetail); // store quotation detail Id
} else {
// 2nd row onward
// when it is available but it it is not empty, create a new row
if (typeof $("#x" + ridx + "_Id_item_code") === 'undefined' || $("#x" + ridx + "_Id_item_code")[0] != "") {
ew.addGridRow('#tbl_s_invoicedtlgrid');
}
ridx = $("#key_count_fs_invoicedtlgrid")[0].value;
var c_part_code = $("#x" + ridx + "_Id_item_code")[0];
var c_qty = $("#x" + ridx + "_qty")[0];
c_part_code.value = kcode;
c_qty.value = fmtDecimal(tQty, 'qty');
$("#x" + ridx + "_Id_item_code").select();
$("#x" + ridx + "_Id_item_code").change();
//$("#x" + ridx + "_Id_quotattoindetl").value(Id_quotationDetail); // store quotation detail Id
// trigger onChange to updateAmount() function;
$("#x" + ridx + "_qty").change();
}
}
async function processFindCode(code) {
found = false;
var rCnt = $("#key_count_fs_invoicedtlgrid")[0].value;
for (j = 1; j < rCnt + 1; j++) {
// loop thru row and col
if ($("#x" + j + "_item_code").val() != null) {
if ($("#x" + j + "_item_code").val() == kcode) {
if ($("#x" + j + "_item_code")[0].style.display != "none") { // visible row only. Deleted row's display is set to hidden.
found = true;
}
break; // exit loop column
}
}
if (found) {
break; // exit loop row
}
} // end for loop rCnt
isFound = found;
return isFound;
}
async function processItemCode(code) {
// notice that we can await a function
// that returns a promise
let isFound = await processFindCode(code);
await delay();
if (!isFound) {
await addItem(code);
}
console.log('Done! ' + code);
//await delay();
//console.log(item.Id_item_code);
}
async function processAPIitem(item) {
for (const itm of item) {
await processItemCode(itm.Id_item_code);
}
//console.log('Done! '+ apiitem.Id_item_code);
}
// main async task to get results
//-------------------------------
async function doTask() {
//get result form API function
let result = await processAPIResult();
//process each API array
for (const item of result) {
await processAPIitem([item]);
}
}
doTask();
Simple answer: $item_code.hide() hides; it isn't a test. Use $item_code.is(':visible') instead.
function processFindCode(code) {
var found = false;
var rCnt = $('#key_count_fs_invoicedtlgrid').val();
for (var j=1; j<rCnt+1; j++) {
if ($('#x' + j + '_item_code').val() != null) {
if ($('#x' + j + '_item_code').val() == code) {
if ($('#x' + j + '_item_code').is(':visible')) {
found = true;
break;
}
}
}
}
return found;
}
Longer answer: Finding the desired element with $('#x' + j + '_item_code') is inefficient especially when performed three times. You can improve matters by leveraging the power of javascript/jQuery and write something like this.
function processFindCode(code) {
var $rows = $('#tbl_s_invoicedtlgrid tbody tr'); // select all table rows in the table's tbody (assumed selector) .
return $rows.get().reduce(function(bool, row) {
return bool || $("id*='_item_code'", row).filter(':visible').filter(function() {
return this.value === code;
}).length > 0;
}, false);
}
This is still not as efficient as it could be. The "id*='_item_code'" selector is pretty nasty but at least it only applies to one row at a time, not the whole DOM.
For vastly improved efficiency, give the item_code element class="item_code" and select with $(".item_code", row). The addItem() function would benefit greatly from the same approach.
Strange phenomenon. socketio
SERVER
i have that code...
socket.on('disconnect', function(){
console.log('user disconnected');
for(var i=0; i<stores.length; i++ ){
var c = stores[i];
if(c.socketid == socket.id){
stores.splice(i,1);
break;
}
}
});
everything goes well with the .splice. If i print the stores array from elsewhere, it displayed correct ...but in this situation
socket.on('disconnect', function(){
console.log('user disconnected');
for(var i=0; i<stores.length; i++ ){
var c = stores[i];
if(c.socketid == socket.id){
for(var i=0; i<stores.length;i++){
console.log(i+" one"+stores[i].name+"-"+stores[i].id)
}
stores.splice(i,1);
for(var i=0; i<stores.length;i++){
console.log(i+" two"+stores[i].name+"-"+stores[i].id)
}
break;
}
}
});
the array has not lost its values, i visit the page from my browser(i connected),
socket.on('storelogged', function (msg){
var storeInfo = new Object();
storeInfo.name = msg.name;
storeInfo.id = msg.id;
storeInfo.socketid = socket.id;
stores.push(storeInfo);
console.log(msg.name + " has connected with " + msg.id + " id." );
});
so, stores pushed. But when i disconnected in the second situation of socket.on('disconnect',callback) the stores array still contains the values( in other words, splice dont work )
comment for giving, much and better information. Also you can test it and see the results
Your embedded for loops are overwriting the i variable from the top level for loop.
Either use let instead of var as in for (let i = 0; ....) for all your for loops so each has a different locally scoped value of i and the inner loops won't overwrite the outer loops or use a different variable name for the embedded for loops or use .forEach() which creates a new variable for the index.
In addition, after you call .splice() on the array you are iterating, you have decrement the current array index from your for loop or you will skip looking at one of the values in the array because the .splice() moved it down into the index spot that you just removed and that your for loop has already iterated.
For example, you can change variable names of the inner for loops like this:
socket.on('disconnect', function () {
console.log('user disconnected');
for (var i = 0; i < stores.length; i++) {
var c = stores[i];
if (c.socketid == socket.id) {
for (var j = 0; j < stores.length; j++) {
console.log(j + " one" + stores[j].name + "-" + stores[j].id)
}
stores.splice(i, 1);
// make sure not to skip the value we just moved into the i slot in the array
i--;
for (var k = 0; i < stores.length; k++) {
console.log(k + " two" + stores[k].name + "-" + stores[k].id)
}
break;
}
}
});
Or, you can use let for the for loops:
socket.on('disconnect', function () {
console.log('user disconnected');
for (var i = 0; i < stores.length; i++) {
var c = stores[i];
if (c.socketid == socket.id) {
for (let i = 0; i < stores.length; i++) {
console.log(i + " one" + stores[i].name + "-" + stores[i].id)
}
stores.splice(i, 1);
// make sure not to skip the value we just moved into the i slot in the array
i--;
for (let i = 0; i < stores.length; i++) {
console.log(i + " two" + stores[i].name + "-" + stores[i].id)
}
break;
}
}
});
Or, you can use .forEach():
socket.on('disconnect', function () {
console.log('user disconnected');
for (var i = 0; i < stores.length; i++) {
var c = stores[i];
if (c.socketid == socket.id) {
stores.forEach(function(item, index) {
console.log(index + " one" + item.name + "-" + item.id)
});
stores.splice(i, 1);
// make sure not to skip the value we just moved into the i slot in the array
i--;
stores.forEach(function(item, index) {
console.log(index + " one" + item.name + "-" + item.id)
});
break;
}
}
});
I'm trying to show alert message including click event on div element that are sought through a loop. The problem is that in any div I click, it is only displayed the alert of the last element. How can I solve? I do not understand the logic being performed.
for (var i = 0; i < this.legend.layerInfos.length; i++)
{
var sNomeDiv = "";
var sMensagem = "";
if (this.legend.layerInfos[i].layer.visible)
{
sNomeDiv = this.legend.id + "_" + this.legend.layerInfos[i].layer.id;
if (this.legend.layerInfos[i].layer.description == "" || this.legend.layerInfos[i].layer.description == "undefined" || this.legend.layerInfos[i].layer.description == "null")
{
sMensagem = "Nenhuma informação cadastrada para a camada " + this.legend.layerInfos[i].title;
}
else
{
sMensagem = this.legend.layerInfos[i].layer.description;
}
//Always display an alert with the text of the last element of the loop
dojo.connect
(
dojo.byId(sNomeDiv),
"onclick",
function()
{
alert(sMensagem + " --> " + sNomeDiv);
}
);
}
}