Javascript - First element of array returns Undefined - javascript

I have a weird situation, where array[0] is returning Undefined, even if there are elements in the array.
Any ideas?
var PLAYER_LIST = [];
function refresh(data){
var players = data.players;
for(var p in players){
var newPlayer = players[p];
var id = newPlayer.id;
if(PLAYER_LIST[id] == undefined){
PLAYER_LIST[id] = createPlayer(newPlayer);
}
var player = PLAYER_LIST[id];
player.position = newPlayer.position;
player.angle = newPlayer.angle;
player.controls = newPlayer.controls;
player.speed = newPlayer.speed;
player.update = 0;
}
console.log(PLAYER_LIST[0]); //returns Undefined
console.log(PLAYER_LIST); //returns entire array (works normally)
console.log(PLAYER_LIST.length); //returns 0 (when it should return 1)
}
refresh(obj); //obj full of new player info
console.log(PLAYER_LIST) returns
[3oPNoqkvaBtAYPGrAAAr: {…}]
3oPNoqkvaBtAYPGrAAAr: {id: "3oPNoqkvaBtAYPGrAAAr", animation: 0,
animationCountTotal: 5, animationCount: 4, saveAngle: 0, …}
length: 0
__proto__: Array(0)

Your list is an array, not an object, so you won't be able to get the player from the list using players['player-id']
You don't need to iterate over the entire list, just simply detect whether or not the player exists, when that's not the case: create one and add it to your list, otherwise update the existing player in the list with the new player data.
Try something like this:
<!DOCTYPE html>
<body>
<script>
var PLAYER_LIST = [{
id: 1,
name: 'john do'
}];
function createPlayer(newPlayer) {
// what ever it is you do here..
return newPlayer;
}
function refresh(data) {
const playerIndex = PLAYER_LIST.findIndex(p => p.id === data.id);
if (playerIndex === -1) {
const newPlayer = createPlayer(data);
PLAYER_LIST.push(newPlayer);
} else {
PLAYER_LIST[playerIndex] = data;
}
}
refresh({ name: 'jane do' }); // I don't exist, create me
refresh({ id: 1, name: 'changed' }); // I exist, update me
console.log('Refreshed list: ', PLAYER_LIST);
</script>
</body>
</html>

Related

How output name player online minecraft-server-util

The console displays the id, name of the players, I need to display only the name list.
How can I do this?
Code:
const util = require('minecraft-server-util');
util.status('xxx.xxx.xx.xxx', { port: xxxxx, enableSRV: true})
.then((response) => {
console.log(response.onlinePlayers);
console.log(response.samplePlayers);
})
response.onlinePlayers outputs to the console: 3 online server
response.samplePlayers outputs to the console:
[
{ id: '54bc4231-79as-3290-bce6-6585c28aa931', name: 'Alexs21' },
{ id: '63c3f66e-c4ff-438a-ba23-4102a70140e6', name: 'Steve12' },
{ id: '30в625d5-305e-205d-a72e-76281654ffd8', name: 'Anton666' }
]
to append that info to the body of the HTML page, use:
for (i in response.samplePlayers) {
$("body").append(response.samplePlayers[i].name);
}
Most efficient way of filtering out would be to use map():
const nameArr = response.samplePlayers.map(obj => obj.name);
//returning only the name property of every object element of response.samplePlayers.
console.log(nameArr); //outputs array - ['Alexs21','Steve12','Anton666']
In case of old browsers, you can simply use -
const nameArr = []; //declare an empty array
for(var i = 0;i < response.samplePlayers.length;i++) {
nameArr.push(response.samplePlayers[i].name); //populate name property to nameArr
}
I think what you're looking for is this:
for(var i = 0 ; i < response.samplePlayers.length; i++){
console.log("name :" + response.samplePlayers[i].name);
}
response.sampleplayers is an array. You simply want to read the value of the property name of each element of this array.
if (response.onlinePlayers != 0) {
for (var i = 0; i < response.onlinePlayers; i++) {
console.log("name :" + response.samplePlayers[i].name);
}
} else {
console.log("No One Is Online");
}
this is what I use and it works

how to loop through array with javascript

I its basic but I am new to javascript. I am trying to loop through the array and match the objects that == my key.
this is what i am using right now, it works but i am only matching the first object that matches, sometimes there will be multiple objects that match.
Here is what i have now
var chartSeries = chartService.getSeries();
var marker.options.subdivision.id = 1345
var matchingSeries = Enumerable.From(chartSeries).Where('x => x.id == "' + marker.options.subdivision.id + '"').ToArray();
var series = {
id: matchingSeries[0].id,
name: matchingSeries[0].name,
data: matchingSeries[0].data,
lineWidth: 5
};
I need to include a for loop to match all objects.
var subIdSeries = [];
var subId = marker.options.subdivision.id;
var series = {
id: matchingSeries[0].id,
name: matchingSeries[0].name,
data: matchingSeries[0].data,
lineWidth: 5
};
for (var i = 0; i < chartSeries.length; i++) {
if (subId == chartSeries.id) {
push.subIdSeries(subId)
}
}
Change
if (subId == chartSeries.id) {
push.subIdSeries(subId)
}
to
if (subId == chartSeries[i].id) {
subIdSeries.push(subId)
}
Without seeing the whole script, from what you have so far, I can suggest:
if (subId == chartSeries[i].id) {
subIdSeries.push(subId)
}

Values are not being saved to the array

I am pretty new to javascript and jquery. I currently have a xml file that I'm trying to parse by using jquery and javascript, but for some reason the values that I store on the array are not being saved.
var categories = new Array(); // Array for the categories
var data = {
categories: []
};
var sources = [
{
src:'',
title: '',
desc: ''
}];
var i = 0;
$.get('fakeFeed.xml', function (info) {
$(info).find("item").each(function () {
var el = $(this);
var categoryName = el.find('category').text();
var p = categories.indexOf(categoryName);
sources[i] = [];
sources[i].src = el.find('media\\:content, content').attr('url');
sources[i].title = el.find("title").text();
sources[i].desc = 'Moscone Center';
if( p == -1) {
categories.push(categoryName);
var category = {
name: categoryName,
videos: []
};
}
i++;
});
});
If i do console.log(categories) it prints all the categories on the array but if I do console.log(categories.length) I keep getting 0...
console.log(categories.length); // This should be outputting 5 but I keep getting 0 for the size.
for (var i=0; i<categories.length; i++) {
var category = {
name: categories[i],
videos: []
};
}
I appreciate any help that anybody can give me. Thanks
$.get function is asynchronous so you should try putting the logging inside the callback function.
$.get('fakeFeed.xml', function (info) {
$(info).find("item").each(function () {
....
});
console.log(categories.length);
});

Change image depending on page title

What I'm trying to do is depending on the page title, an image in the body would change. For example, if the page title is "We Love Apples," the image in the body would be an apple. If the title contains another fruit, it would show that other fruit. If the page title doesn't contain any word that the script is looking for, then there would be a default image in the body.
I did find this script from http://www.codingforums.com/archive/index.php/t-218600.html but I can't seem to make it work.
Anyone has any tips or pointers? Appreciate the help!
<!doctype html>
<html>
<title>2image</title>
<head>
</head>
<body>
<div><img src="" alt="anImageDesc" name="myimage" width="50px" height="50px" id="someImage" />
</div>
<script type="text/javascript">
var imgs = [
"http://www.domain.com/images/image_255 Company_Name.jpg",
"http://www.domain.com/images/image_256 Company_Name.jpg",
"http://www.domain.com/images/image_257 Company_Name.jpg" //no comma after last image
];
var el = document.getElementById("someImage");
var title = document.title;
for (var i=0;i<imgs.length;i++){
if (imgs[i].indexOf(title) != -1) {
el.src = imgs[i];
break;
} else {el.src = "image_256.gif"} //a default image incase nothing is found
}
</script>
</body>
</html>
See this: DEMO
I would suggest having a key/value map of tokens to look for in the title, and associating the appropriate image with that token:
var images = {
'very large apple' : 'http://www.domain.com/images/very_large_apple_image_here.jpg',
'large apple' : 'http://www.domain.com/images/large_apple_image_here.jpg',
'apple' : 'http://www.domain.com/images/apple_image_here.jpg',
'orange' : 'http://www.domain.com/images/orange_image_here.jpg'
};
var defaultImage = images['apple']; //Set your default here.
var imageElement = document.getElementById("someImage");
var title = document.title.toLowerCase();
var source = null;
for (var t in images) {
if (title.indexOf(t.toLowerCase()) != -1) {
source = images[t]; //Found a match.
break;
}
}
if (!source) source = defaultImage;
imageElement.src = source;
Use document.title to get the window title, and set your image based on that. I used toUpperCase() to make sure you find the text you are looking for regardless of case. search() will return -1 if the text is not found.
if(window.title.toUpperCase().search('APPLE') > 0)
{
//change image to apple
}
else if(document.title.toUpperCase().search('ORANGE') > 0)
{
//change image to orange
}
else
{
//use the default image
}
Define what fruits to look for, then check the title to see if it contains any of the fruits, then find the appropriate image :
var fruits = [
'apple',
'orange',
'grape'
]
var imgs = [
"http://www.domain.com/images/image_255_grape.jpg",
"http://www.domain.com/images/image_256_orange.jpg",
"http://www.domain.com/images/image_257_apple.jpg"
];
var fruit = 'apple', // default
img = '';
// check the title for fruit
for (var i=0; i<fruits.length; i++) {}
if ( document.title.indexOf(fruits[i]) != -1 ) fruit = fruits[i];
}
//find matching image
for (var i=0; i<imgs.length; i++) {}
if ( imgs.indexOf(fruit) != -1 ) img = imgs[i];
}
var el = document.getElementById("someImage");
el.src = img;
Create a lookup:
var myList = {
images: [{
id: "grape",
name: "somelocation/file.png"
}, {
id: "crabapple",
name: "c:/images/brightblue.png"
}, {
id: "lime",
name: "grassgreen.png"
}, {
id: "bannana",
name: "dollarbill.png"
}]
};
var lookup = {};
// create refernece to list above and use it everywhere
lookup.list = myList;
for (var i = 0, len = lookup.list.images.length; i < len; i++) {
lookup[lookup.list.images[i].id] = lookup.list.images[i];
}
alert(lookup['lime'].name);
and for the title:
lookup[document.title].name;

Get Next and Previous Elements in JavaScript array

I have a large array, with non-sequential IDs, that looks something like this:
PhotoList[89725] = new Array();
PhotoList[89725]['ImageID'] = '89725';
PhotoList[89725]['ImageSize'] = '123';
PhotoList[89726] = new Array();
PhotoList[89726]['ImageID'] = '89726';
PhotoList[89726]['ImageSize'] = '234';
PhotoList[89727] = new Array();
PhotoList[89727]['ImageID'] = '89727';
PhotoList[89727]['ImageSize'] = '345';
Etc....
I'm trying to figure out, given an ID, how can I can get the next and previous ID... So that I could do something like this:
<div id="current">Showing You ID: 89726 Size: 234</div>
Get Prev Get Next
Obviously, if we're at the end or beginning of the array we just a message...
Why don't you add properties 'Prev' & 'Next' to that array?
PhotoList[89725] = new Array();
PhotoList[89725]['Prev'] = 89724;
PhotoList[89725]['Next'] = 89726;
PhotoList[89725]['ImageID'] = '89725';
PhotoList[89725]['ImageSize'] = '123';
This is just 'doubly-linked list' data structure.
Based on your example the IDs are sequential...
This is another way of writing your example. new Array() really isn't what you should be using because those are objects you are creating. Also, I left the numbers as strings, but I'm not sure why you would want to do that. You could add next and prev like kuy suggested
PhotoList[89725] = {ImageID: '89725',
ImageSize: '123'};
PhotoList[89725] = {ImageID: '89726',
ImageSize: '234',
Next: '89727',
Prev: '89725'};
PhotoList[89725] = {ImageID: '89727',
ImageSize: '345'};
All of these are accessible just like your other structure.
There's really no way other than to iterate through the possible ids sequentially until you find one which has an entry in your array. For example:
function findClosest(arr, id, increasing) {
var step = increasing ? 1 : -1;
for(var i=id+step; i>=0 && i<=max_id; i+=step)
if( arr[id] )
return id;
}
Obviously, this approach requires that you keep track of the max_id so that you don't iterate forever; here I assume that it's a global variable, but you might want to make it a parameter to the findClosest function. You'd call this function like so:
var prev = findClosest(arr, id, false);
var next = findClosest(arr, id, true);
I agree with the rest quotes you should be using objects not an array. Also make sure you create new arrays using the literal notation and not the new keyword with built in types. The new keyword is bad news and you could clobber the global object. Check out JSLint.
var a = new Array(); //bad dont use
var a = []; //this is the best way to create a new array
var o = {}; //create new objects like this
As for the problem at hand. Why not write a simple container that has its own internal counter?
function PhotoListContainer(PhotoList)
{
if(PhotoList === undefined)
throw("no photo list");
this.counter = 0;
var self = this;
this.current = function(){
return PhotoList[self.counter];
};
this.next = function(){
return PhotoList[self.counter + 1];
};
this.prev = function(){
return PhotoList[self.counter - 1];
};
// You could even write a function that loops each value from the current counter :)
this.each_from_counter = function(callback){
for(var i = self.counter; i < PhotoList.length; i++)
{
callback(PhotoList[i], i);
self.counter++;
}
};
}
//use
var pc = new PhotoListContainer(PhotoList);
pc.counter = 500;
pc.next(); //returns the 501st object
pc.prev(); //returns the 499th object
pc.each_from_counter(function(photo, index){
photo.somehting;
});
No arrays at all are better..
images = {
0: {
size: 12345, /* dont realy need as you can use JS to mesure the size. */
title: "day 1 on holiday"
},
1: {
size: 13549, /* dont realy need as you can use JS to mesure the size. */
title: "day 2 on holiday"
},
2: {
size: 16548, /* dont realy need as you can use JS to mesure the size. */
title: "day 3 on holiday"
},
}
for(x in images){
/* x = "the id of the image." */
url[] = "/images/" + x + ".png";
title[] = images[x].title;
size[] = images[x].size;
console.log("File: " + url[x] + " , Title: " + title[x] + " , Size: " + size + "bytes")
}
var sibNum = 0;
var sibList = [];
var prevSiblingID = false;
for (n in w) {
sibNum++;
sibList[n] = {
title : n,
prevSiblingID : prevSiblingID
};
if (prevSiblingID) {
sibList[prevSiblingID].nextSiblingID = n;
}
prevSiblingID = n;
};
sibList[prevSiblingID].nextSiblingID = false;
you can use grep function and calculate prev or next item of specified array:
object = $.grep(data, function(e) {
if(e.id == yourId) {
return data[data.indexOf(e) + 1]; // or -1 for prev item
}
});
i think your image list will come from DB so you may can try this code, this code is working for me.
<?
$prev="";
$next="";
$cur=0;
$i=0;
$pid=$_GET['pid'];
while($rowcon=mysql_fetch_assoc($result))
{
$arr[$i]=$rowcon['pid'];
if($rowcon['pid']==$pid)
{
$cur=$i;
}
$i++;
}
if($cur<$num_rows)
$next=$arr[$cur+1];
else
$next="";
if($cur>0)
$prev=$arr[$cur-1];
else
$prev="";
echo $prev." ".$cur." ".$next;
?>

Categories