Matching strings don't trigger condition in Javascript - javascript

I am trying to do a very simple stock counting app, and display dynamically the stocks for each item. When I try to pair the button with its item, it doesn't work, even though the 2 strings are actually a match.
Here is the faulty function:
socket.on('Stock init', (data) => {
items = data.items;
displayStock(items);
});
function displayStock(items) {
fridgeItem.forEach((fridgeItem) => {
for (let i = 0; i < items.length; i++) {
var databaseProduct = items[i].name;
var databaseQuantity = items[i].chilled.toString();
console.log(fridgeItem.textContent, databaseProduct);
}
if (fridgeItem.textContent === databaseProduct) {
fridgeItem.textContent = databaseProduct + ' ' + databaseQuantity;
} else {
console.log('err');
}
});
}
Answer might be stupid but I can't see it at the moment. Thanks

Related

AngularFire2 iterate through array of objects and get data from realtime database

I have to go through an array of items and fetch the prices in the realtime database, but I want to show a loading message on start and after I finish loading I want to remove the loading message, but the way I did the message does not work its removed before the end of loading:
let loading = this.loadingCtrl.create({
content: 'Waiting...'
});
loading.present();
for (let i = 0; i <= this.Cart.length - 1; i++) {
let product = this.db.object('/menuItems/' + this.Cart[i].item.itemId);
product.valueChanges().subscribe((prodData: any) => {
if (prodData != null) {
this.Cart[i].item.price = prodData.price[0];
}
});
}
loading.dismiss();
How can I do this correctly?
You need to hide the loading indicator inside the subscriber. The simplest way is to hide it when the first data comes in:
for (let i = 0; i <= this.Cart.length - 1; i++) {
let product = this.db.object('/menuItems/' + this.Cart[i].item.itemId);
product.valueChanges().subscribe((prodData: any) => {
if (prodData != null) {
this.Cart[i].item.price = prodData.price[0];
}
loading.dismiss();
});
}
A bit more tricky is to hide it after all data comes back, but it doesn't have to be too hard. A simple way is to count how many responses you've gotten back. Once that is the same as the number of items in the cart, you can hide the loading indicator.
var responseCount = 0;
for (let i = 0; i <= this.Cart.length - 1; i++) {
let product = this.db.object('/menuItems/' + this.Cart[i].item.itemId);
product.valueChanges().subscribe((prodData: any) => {
if (prodData != null) {
this.Cart[i].item.price = prodData.price[0];
}
if (responseCount++ == this.Cart.length) loading.dismiss();
});
}

then not working as expected in JS promise

I'm trying to extract text from a pdf and then return a number that represents how many pages of the pdf are matched by a regex that I define.
My problem is that, rather than periodically checking whether or not the text of a single page is part of the match, my function divides the pieces up into smaller sections than pages. Count is meant to increment only after an entire page has been read.
getnopages: function(){
var fulltext = ""
var partialmatch;
var somerx = /something/
return pdfjs.getDocument(data).then(function(pdf) {
var pages = [];
pageNumbers = [];
for (var i = 0; i <= 6; i++) {
pages.push(i);
}
var found = false;
var count = 1;
return Promise.all(pages.map(function(pageNumber) {
pageNumbers.push(pageNumber);
return pdf.getPage(pageNumber + 1).then(function(page)
return page.getTextContent().then(function(textContent) {
return textContent.items.map(function(item) {
fulltext+=item.str+'&&&';
return item.str;
}).join('&&&');
});
}).then(function(){
count++;
console.log('the count is ' + count)
var partialmatch;
try {
partialmatch = fulltext.match(somerx)[0]
console.log('the match: ' + partialmatch)
var full = fulltext.slice(0, fulltext.length-3)
console.log('the full text ' + full)
if (fulltext && partialmatch!==full && !found){
found = true;
console.log('now we found our number: ' + count) // this finds where the full text differs from the partial text but returns a number too large to be a page number
}
}
catch(e){
console.log(e)
}
});
}));
}
Can anyone help me figure out how to rewrite this so that count is incrementing page numbers correctly?
I don't really know where is the problem in your code but I just suggest you to avoid too many nestings with promises. You can reduce nesting by chaining your promise like below:
getnopages: function() {
var somerx = /something/
return pdfjs.getDocument(data).then(function(pdf) {
var pages = [];
pageNumbers = [];
for (var i = 0; i <= 6; i++) {
pages.push(i);
}
var found = false;
var count = 1;
var promises = pages.map(pageNumber => {
pageNumbers.push(pageNumber);
return pdf.getPage(pageNumber + 1).then(page => {
return page.getTextContent();
}).then(textContent => {
return textContent.items.map(item => {
fulltext += item.str +'&&&';
return item.str;
}).join('&&&');
});
});
return Promise.all(promises).then(() => {
...
});
});
}

Displaying all the items in an array using jquery and json

I am trying to get all the items in an array to show using json and jquery from the song of ice and fire api. I can only get one item to show from each of the arrays.
Here is the codepen: https://codepen.io/frederickalcantara/pen/aWeXOz
var data;
$.getJSON(characters[i], function(json) {
data = json;
var alliance = $('#alliance');
for (var i = 0; i < data.allegiances.length; i++) {
if (i === data.allegiances.length - 1) {
$.getJSON(data.allegiances[i], function(json1) {
alliance.html(json1.name);
});
} else {
$.getJSON(data.allegiances[i], function(json1) {
alliance.html(json1.name + ', ');
});
}
}
const title = $('#title');
if (data.titles.length === "") {
return 'N/A';
} else {
for (i = 0; i < data.titles.length; i++) {
if (i === data.titles.length - 1) {
title.html(data.titles[i]);
} else {
title.html(data.titles[i]) + ', ';
}
}
const tv = $('#seasons');
for (var i = 0; i < data.tvSeries.length; i++) {
if (i === data.tvSeries.length - 1) {
tv.html(data.tvSeries[i]);
} else {
tv.html(data.tvSeries[i] + ', ');
}
}
const actor = $('#actors')
if (json.playedBy === "") {
return 'N/A';
} else {
actor.html(json.playedBy);
}
});
The main problem is your loop. You keep replacing the value in the html element until the last value in the array. You can simplify this code like this:
title.html(data.titles.join(','));
which replaces all of this:
for (i = 0; i < data.titles.length; i++) {
if (i === data.titles.length - 1) {
title.html(data.titles[i]);
} else {
title.html(data.titles[i]) + ', ';
}
}
Update: Handling the allegiances.
Using a Promise here is important because you are making a number of AJAX calls and you need to be sure that they are resolved before attempting to display them. You can replace the entire for loop for the allegiances like this:
Promise.all(data.allegiances.map(function(ally){
return new Promise(function(resolve, reject){
$.getJSON(ally, function(json) {
resolve(json.name);
});
});
}))
.then(function(allies){
alliance.html(allies.join(', '));
});

Javascript - Creates new array instead of incrementing

I'm making a simple twitter app to work on my javascript.
The code below is supposed to identify every tweets location and count the number of tweets per location.
However, it doesn't increment, it just creates a new array.
What is wrong with my code? How can I make it better?
Thank you
var Twitter = require('node-twitter'),
twit = {},
loc = [];
twit.count = 0;
var twitterStreamClient = new Twitter.StreamClient(
//credentials
);
twitterStreamClient.on('close', function () {
console.log('Connection closed.');
});
twitterStreamClient.on('end', function () {
console.log('End of Line.');
});
twitterStreamClient.on('error', function (error) {
console.log('Error: ' + (error.code ? error.code + ' ' + error.message : error.message));
});
twitterStreamClient.on('tweet', function (tweet) {
if (loc.indexOf(tweet.user.location) === -1) {
loc.push({"location": tweet.user.location, "locCount": 1});
} else {
loc.loation.locCount = loc.loation.locCount + 1;
}
console.log(loc);
});
var search = twitterStreamClient.start(['snow']);
You need to rewrite on tweet callback:
var index = loc.reduce(function(acc, current, curIndex) {
return current.location == tweet.user.location ? curIndex : acc;
}, -1);
if (index === -1) {
loc.push({"location": tweet.user.location, "locCount": 1});
} else {
loc[index].locCount++;
}
Array.indexOf is not matching as you think it is. You're creating a new object and pushing it into the array, and regardless of whether its properties match a different object perfectly, it will not be === equal. Instead, you have to find it manually:
var foundLoc;
for (var i = 0; i < loc.length; i++) {
if (loc[i].location.x === location.x)
foundLoc = loc[i];
break;
}
}
if (!foundLoc) {
loc.push({location: location, count: 0});
} else {
foundLoc.count++
}

Count times a value is repeated in data fetched using REST call

I'm fetching data from SharePoint using REST, and everything works just fine, except that I would like to count the times the same item appears.
This is the jQuery:
var url = "https:xxxxxxxx/_vti_bin/ListData.svc/RMSD_Tasks?$orderby=TypeOfIssueValue asc,StatusValue desc&$filter=StatusValue ne 'Completed'&groupby=TypeOfIssueValue/StatusValue";
var lastIssue = '';
$.getJSON(url, function (data) {
$('#totalCounter').text(data.d.results.length);
for (var i = 0; i < data.d.results.length; i++) {
var dateReceived = data.d.results[i].DateReceived;
dateReceived = new Date(parseInt(dateReceived.replace("/Date(", "").replace(")/", ""), 10)).toLocaleString('en-US', {
year: 'numeric',
month: 'numeric',
day: '2-digit'
});
var issue = data.d.results[i].TypeOfIssueValue;
console.log(data.d.results[i].TypeOfIssueValue);
if (issue != lastIssue) {
lastIssue = issue;
$('#myDataList').append('' + issue + '<span class="badge">' + issue.length + '</span>');
}
}
});
I need to count how many time a specific TypeOfIssueValue appears. When I see the console it shows exactly what I would like to add to me info:
I just added a issue.length in the badge were I want to insert the number for the sake of just having something there, but I know it won't show what I want. Thanks!
var data = {
d: {
results: [
{ TypeOfIssueValue: '456' },
{ TypeOfIssueValue: '123' },
{ TypeOfIssueValue: '789' },
{ TypeOfIssueValue: '123' }
]
}
};
var filteredItems = data.d.results.filter(function(item){
return item.TypeOfIssueValue == '123';
});
var count = filteredItems.length;
document.getElementById("output").innerHTML = "Number of items with value '123': " + count;
<div id="output"/>
You could first map the TypeOfIssueValue values to a new array and then count each occurence based on this answer.
The code would be :
var a = data.d.results.map(function(issue) {
return issue.TypeOfIssueValue
});
result = {};
for (i = 0; i < a.length; ++i) {
if (!result[a[i]])
result[a[i]] = 0;
++result[a[i]];
}
The result will be an object with property being type of issue and value being the count of each.
Let me know if this makes sense.
Thanks #srinivas. I accepted your response, although I made some modifications, just in case they are useful to someone else.
I added a class to the span badge and added a new array to push the issues:
issuesArray.push(data.d.results[i].TypeOfIssueValue);
$('#myDataList').append('' + issue + '<span class="badge badgeSpan"></span>');
Then I addded a done() to run after the getJSON:
.done(
function(){ var resultado = foo(issuesArray)[1];
console.log(resultado);
var badges = $('.badgeSpan');
for (var j = 0; j < resultado.length; j++){
badges[j].innerHTML = resultado[j];
}
});
Last I made a small modificfation to the function foo() that you provided:
testArray = [];
function foo(arr) {
var a = [], b = [], prev;
for ( var i = 0; i < arr.length; i++ ) {
if ( arr[i] !== prev ) {
a.push(arr[i]);
b.push(1);
} else {
b[b.length-1]++;
}
prev = arr[i];
}
testArray.push(a,b)
return testArray;
}
This maybe a very unorthodox solution, but it worked for me. Thanks again.

Categories

Resources