Setting Correct Boolean Conditions - javascript

I am working on practicing booleans (where in the code below, I'm representing the number of times a fruit is counted, essentially that number will be what they can afford to the price, if that makes sense) and the code I am working on seems to be working, but the conditionals I have set are only returning as false and not as true and vice versa when they are swapped.
I'm just wondering if there is an issue with the logic that I currently have.
Here is the data that I have:
items = {
count: 100,
fruits: [
{ id: 'apple', price: 50 },
{ id: 'orange', price: 200 },
{ id: 'banana', price: 500 }
]
};
});
('returns true if the person can afford the item', function() {
const result = code.affordItem(items, 'apple');
expect(result).to.be.equal(true);
});
('returns false if person cannot afford the item', function() {
const result = code.affordItem(items, 'orange');
expect(result).to.be.equal(false);
Here is the code that I have:
function affordItem(items, itemId) {
if (items.count >= items.fruits.quantity && items.fruits.id === itemId) {
return true;
} else {
return false;
}
}
Any guidance would be much appreciated!

function affordItem(items, itemId) {
if (items.count >= items.fruits.length && items.fruits.id === itemId) {
return true;
} else {
return false;
}
}
Try this, i assumed you want to get the quantity of fruits so use array.length instead.

Related

How to see if values are in the same "line" within an object in javascript

Not sure how to approach this problem, but I want to see if two values are in the same 'line'
var inventory_needed = [
{ section: "hardware", supplies: "hammers" },
{ section: "plumbing", supplies: "pipes" },
{ section: "garden", supplies: "grass seeds" },
{ section: "cleaning supplies", supplies: ["hand sanitizer", "detergent"] },
{ section: "appliances", supplies: ["fridges", "dishwashers"] }
];
psuedocode of what I want to try to attempt
if(section.value && supplies.value in the same line) {
return true;
}
else {
return false;
}
//example 1
if("appliances" && "fridges" in the same line) {
return true; //would return true
}
else {
return false;
}
//example 2
if("plumbing" && "fridges" in the same line) {
return true;
}
else {
return false; //would return false
}
By in the same line, you seem to mean defined within the same object in the array. If that's correct, the way to do that is like this:
function inTheSameLine(section, supplies){
return inventory_needed.some(obj => {
return obj.section === section && (
obj.supplies === supplies || (
Array.isArray(obj.supplies) && obj.supplies.includes(supplies)
)
);
});
}
The JavaScript array some function returns true if any of the array elements satisfy the condition.

JSON property not updating the value for new key on third function call

I apologise in advance for the title, I haven't found what I have been looking for while debugging but I may not know the correct terms to search for.
I have the following object:
const Game = {
user: {
tool: {
displayName: "shovel",
level: 0,
max: 1,
},
backpack: {
level: 0,
max: 10,
contents: {
ice: 5,
}
}
},
locations: {
lifePod: {
displayName: "Life Pod",
loseOxygen: false
},
icyPlain: {
displayName: "Ice Plain",
loseOxygen: true,
materials: {
type: "ice",
}
},
metalPlain: {
displayName: "Metal Plain",
loseOxygen: true,
materials: {
type: "metal",
}
}
}
};
I would like to use the following function to increase the count of the item in ice by 1. This works 100% of the time correctly, however when I try to use "metal" instead, it only allows a maximum of 2.
function mineResource(locationName) {
let newLocation = Game.locations[locationName];
if (Game.user.currentLocation != "lifePod" && newLocation.materials != undefined && backpackNotFull()) {
var alreadyInserted = false;
materialType = newLocation.materials.type; //ice
materialAmount = Game.user.tool.max; //1
let {backpack} = Game.user;
if (backpack.contents != null || backpack.contents != undefined) {
for (item in backpack.contents) {
if (item == materialType) {
Game.user.backpack.contents[materialType] += Game.user.tool.max;
alreadyInserted = true;
refreshValues();
} else if (alreadyInserted) {
null;
} else {
Game.user.backpack.contents[materialType] = materialAmount;
refreshValues();
}
};
};
};
}
I am confused by the fact that this function works fine with Ice but not Metal. As a test I changed:
contents: {
ice: 5,
}
to:
contents: {
ice: 5,
metal: 5,
}
And call Game.user.backpack.contents showed only {ice: 5} and calling contents.metal was undefined. I had definitely saved and refreshed. Unfortunately as I am a beginner I don't know what I don't know and it's hard to search for this. I have a put console logs underneath the "if (item == materialType) {" line and they were outputting but not increasing the counter.
If you want to see the whole code it's on http://oxygen.meddleso.me/main.js
EDIT: I did just remove Ice, and made metal the default with 5 and now Metal goes up by 1 normally, but if I add Ice like I was adding metal, Ice only goes up to 2 now.
When you add metal, but have ice, before adding metal you do
} else {
Game.user.backpack.contents[materialType] = materialAmount; // remove this line
refreshValues();
}
So when mining metal you do contents['metal'] = 1 (on ice loop) and later contents['metal'] += 1 (on metal loop)... Since you are looping over item set contents[item]. But I´m sure you would not want to set contents['ice'] = 1 either when mining metalPlain, so just remove this line.

Vue v-for on first item containing property X call a method

Let's say I have a component which repeats with a v-for loop like so:
<hotel v-for="(hotel, index) in hotels"></hotel>
And my hotels array would look like so:
[
{
name: false
},
{
name: false
},
{
name: true
},
{
name: true
}
]
How could I perform an action when my v-for loop encounters the property name set to true only on the very first time it encounters this truthy property?
I know I could probably cache a property somewhere and only run something once and not run again if it has been set but this does not feel efficient.
Use a computed to make a copy of hotels where the first one has an isFirst property.
computed: {
hotelsWithFirstMarked() {
var result = this.hotels.slice();
var first = result.find(x => x.name);
if (first) {
first.isFirst = true;
}
return result;
}
}
Just use computed source
HTML
<div v-for="(hotel, index) in renderHotels"></div>
JS
export default {
name: 'message',
data () {
return{
hotels:[
{
name: false
},
{
name: false
},
{
name: true
},
{
name: true
}
] ,
wasFirst : false
}
},
methods:{
},
computed:{
renderHotels(){
return this.hotels.map((hotel)=>{
if(hotel.name && !this.wasFirst){
this.wasFirst = true;
alert('First True');
console.log(hotel);
}
})
}
}
}
Best way is to use filter function.
data() {
return {
firstTime: false,
};
},
filters: {
myFunc: function (hotel) {
if (hotel.name && !this.firstTime) {
//perform some action
this.firstTime = true;
}
}
}
<hotel v-for="(hotel, index) in hotels | myFunc"></hotel>

Angular - Only push to array if unique

I have an Angular application that collects values of items for an invoice, I want to make sure only unique items are being added to this collection but am having no luck.
I am pushing 3 pieces of information to this collection: id, price, and type. I want to make sure there is nothing in the collection currently matching those 3 points.
// My container
$scope.invoice = {
items: [{
}]
}
$scope.addPhoto = function() {
console.log('Withdrawing Photo: '+ $scope.item.id);
if ($scope.invoice.items.indexOf(item.id) != $scope.item.id)
{
$scope.invoice.items.push({
id: $scope.item.id,
price: $scope.item.price,
type: 'photo'
});
}
}
// Trying to avoid collections like this
invoice: {
items:
[ { } , {
id: 25
price: 0
type: photo
} , {
id: 25
price: 0
type: photo
} ]
}
.filter is pretty much what you need.
$scope.addPhoto = function() {
console.log('Withdrawing Photo: '+ $scope.item.id);
var matches = $scope.invoice.items.filter(function(datum) {
return datum.id === $scope.item.id &&
datum.price === $scope.item.price &&
datum.type === $scope.item.type;
});
if (!matches.length)
{
$scope.invoice.items.push({
id: $scope.item.id,
price: $scope.item.price,
type: 'photo'
});
}
}
Semi-contrived JSFiddle
This is the solution I came up with to solve my problem, hopefully it helps someone else.
$scope.addPhoto = function () {
console.log('Withdrawing Photo: ' + $scope.item.id);
var newItemId = $scope.item.id;
var newItemPrice = $scope.item.price;
var newItemType = 'photo';
var matches = true;
// Make sure user hasnt already added this item
angular.forEach($scope.invoice.items, function(item) {
if (newItemId === item.id && newItemPrice === item.price && newItemType === item.type) {
matches = false;
$scope.message = 'You have already selected to withdraw this item!';
}
});
// add item to collection
if (matches != false) {
$scope.invoice.items.push({
id: $scope.item.id,
price: $scope.item.price,
type: 'photo'
});
$scope.total += $scope.item.price;
$scope.message = 'Total Amount Selected';
}
};
YOu can simple pop opposite of push
array.splice(array.pop(item));

Function to add and replace items in observable array

Im trying to write a function that 1. adds an item to an observable array and 2. replaces the item if it already exists in the array
self.addNotification = function (name, availability, note) {
//see if we already have a line for this product
var matchingItem = self.notifications.indexOf(name);
if (matchingItem !== undefined) {
self.notifications.replace(self.notifications()[index(matchingItem)],
new Notification(self, name, availability, note));
}
else {
self.notifications.push(new Notification(self, name, availability, note));
}
};
What am I doing wrong?
Regards Anders
Here is my answer: fiddle
Hit F12 in Chrome or use FireBug in FireFox to see console log output.
var notifications = {
notifs: [],
updateNotifications: function(notification) {
'use strict';
var matchIndex;
for (matchIndex = 0; matchIndex < this.notifs.length; matchIndex += 1) {
if (this.notifs[matchIndex].name === notification.name) {
break;
}
}
if (matchIndex < this.notifs.length) {
this.notifs.splice(matchIndex, 1, notification);
} else {
this.notifs.push(notification);
}
}
};
notifications.updateNotifications({
name: 'John',
available: false,
note: "Huzzah!"
});
notifications.updateNotifications({
name: 'Jane',
available: true,
note: "Shazam!"
});
notifications.updateNotifications({
name: 'Jack',
available: true,
note: "Bonzai!"
});
notifications.updateNotifications({
name: 'Jane',
available: false,
note: "Redone!"
});
console.log(notifications);​
Well, Array.prototype.indexOf never returns undefined. Its either -1 (not found) or any number starting with 0 for the array index.

Categories