Loop through 2 select options and show API best match - loops

I want to show the best results (of "plants") from my 2 select options: "sunlight" and "water". API console.log is in the code: https://jsfiddle.net/Luckzzz/1p8bk0g5/
I want to show plants based on the combination of these 2 select options..
const url = 'https://front-br-challenges.web.app/api/v2/green-thumb/?sun=high&water=regularly&pets=false';
let sunlight = $('#sunlight');
sunlight.empty();
sunlight.append('<option selected="true" disabled>Choose sunlight</option>');
sunlight.prop('selectedIndex', 0);
let water = $('#water');
water.empty();
water.append('<option selected="true" disabled>Choose water amount</option>');
water.prop('selectedIndex', 0);
$.getJSON(url, function (data) {
console.log(data);
$.each(data, function (key, entry) {
// Populate SUNLIGHT dropdown:
sunlight.append($('<option></option>')
.attr('value', entry.abbreviation)
.text(entry.sun));
// Populate WATER dropdown:
water.append($('<option></option>')
.attr('value', entry.abbreviation)
.text(entry.water));
})
});

Not sure if I understood your question correctly. You can check this fiddle.
const url = 'https://front-br-challenges.web.app/api/v2/green-thumb/?sun=high&water=regularly&pets=false';
let selectedSun, selectedWater, globalData = [];
let sunlight = $('#sunlight');
sunlight.empty();
sunlight.append('<option selected="true" disabled>Choose sunlight</option>');
sunlight.prop('selectedIndex', 0);
let water = $('#water');
water.empty();
water.append('<option selected="true" disabled>Choose water</option>');
water.prop('selectedIndex', 0);
sunlight.on('change', function() {
selectedSun = this.value;
showImages();
});
water.on('change', function() {
selectedWater = this.value;
showImages();
});
const showImages = () => {
$("#items").empty();
globalData.forEach(item => {
if (!selectedWater || (selectedWater && item.water === selectedWater) &&
(!selectedSun || (selectedSun && item.sun === selectedSun))) {
let img = document.createElement('img');
img.src = item.url;
$("#items").append(img);
}
})
}
$.getJSON(url, function (data) {
console.log(data);
globalData = data;
const sunlights = data.reduce((acc, curr) => {
if (!acc.includes(curr.sun)) acc.push(curr.sun)
return acc;
}, []);
const waterTypes = data.reduce((acc, curr) => {
if (!acc.includes(curr.water)) acc.push(curr.water)
return acc;
}, []);
$.each(sunlights, function (key, entry) {
sunlight.append($('<option></option>')
.attr('value', entry)
.text(entry));
})
$.each(waterTypes, function (key, entry) {
water.append($('<option></option>')
.attr('value', entry)
.text(entry));
})
});
In short, I:
reduced those two lists, so you don't have duplicated
added method to show images, when one of selects changes

Related

Express returns empty Array, but array is fine

All things are going right, when I try to log array it writes everything true but when I try to return as response, it goes empty to front-end. I'm not sure why this is happening, the normal messages array works fine. I don't know why.
console.log('messageye girdi');
MessageModel.find({
receiver: req.body.uuid,
read: false
}).then((Messages) => {
function removeDups(names) {
let unique = {};
names.forEach(function(i) {
if (!unique[i]) {
unique[i] = true;
}
});
return Object.keys(unique);
}
let Users = [];
Messages.forEach(Message => {
Users.push(Message.sender);
})
const nonduplicate = removeDups(Users);
console.log(nonduplicate);
const MessageUsers = [];
var bu = 0;
nonduplicate.forEach(User => {
UserModel.findOne({
uuid: User
}).then((UserData) => {
console.log(UserData.username);
MessageUsers.push(UserData.username);
console.log(MessageUsers);
})
bu++;
if (bu = nonduplicate.length) {
console.log("bu mu acaba " + JSON.stringify(MessageUsers));
let ArrayVer = Object.assign({}, MessageUsers);
return res.send({
success: true,
users: MessageUsers
});
}
});

An empty array is returned when calling $http.get it within a service [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 3 years ago.
I want to get the name from an array that is being generated from $http.get, however this is returning an empty array. When i do a console it see the array populated however when i loop inside the array to get the value of name property based on whether an id is equal to a certain, the array is empty.
In my controller i have a service call that shall return the name value.
var params = { Id: $scope.Id, SettingId: $scope.SettingId };
$scope.selectedUserName = helloService.getSelectedUserName($scope.UserId, params);
In my service
I have used the getUserList function to populate the list of user in a dropdown and it works by generating the array with the values.
However When i got another page , i want to be able to display the name of the selected user, so I wanted to use the same getUserList function to retrieve the name
this.getUserList = function (val) {
var usersObj = [];
var url = "/api/v1/hello/getusers";
var params = { Id: val.Id, SettingId: val.SettingId };
var config = { params: params };
var promise = $http.get(url, config)
.then(function (response) {
angular.forEach(response.data, function (key, value) {
angular.forEach(key, function (k, index) {
usersObj[index] = ({ userId: k.userId, name: k.name});
});
});
},
function errorCallback(response) {
console.log("Unable to perform get request");
throw response;
});
var usersList = usersObj;
return usersObj;
};
this.getSelectedUserName = function (id, param) {
var name = "";
var userList =this.getUserList(param);
angular.forEach(userList, function (value, key) {
if (value.userId == id)
name = value.name;
});
return name;
}
Array length is 0 but if i do a console.log(userList) before the loop , the array display the list of user data
this.getSelectedUserName = function (id, param) {
var name = "";
var userList =this.getUserList(param);
console.log(userList) ;
angular.forEach(userList, function (value, key) {
if (value.userId == id)
name = value.name;
});
return name;
}
Thank you for kind responses.
Please see screenshot
This is simple Javascript, not specific to Angular. You can do
userList.forEach(user => {
if(user.userId === id) {
name = user.name;
}
});
return name;
you can try like this.
here we are using a async await.
Service
this.getUserList = function (val) {
var usersObj = [];
var url = "/api/v1/hello/getusers";
var params = { Id: val.Id, SettingId: val.SettingId };
var config = { params: params };
return new Promise((resolve, reject) => {
$http.get(url, config)
.then(function (response) {
angular.forEach(response.data, function (key, value) {
angular.forEach(key, function (k, index) {
usersObj[index] = ({ userId: k.userId, name: k.name});
});
});
},
function errorCallback(response) {
console.log("Unable to perform get request");
throw response;
});
var usersList = usersObj;
resolve(usersObj);
});
};
this.getSelectedUserName = async function (id, param) {
var name = "";
var userList = await this.getUserList(param);
console.log(userList);
angular.forEach(userList, function (value, key) {
if (value.userId == id)
name = value.name;
});
return name;
}
let me know if it is working or not.
EDIT:
If you're only trying to match one id in the array of users you don't even need to loop:
anArray = source.filter(source => source.toLowerCase().indexOf(id) === 0);
or
anObject = source.find(obj => obj.id === id);
Which Angular version is this? Your tag denotes 2.+ but you have $scope there which is ng1.x
Why can't you use ngFor in your view since you already have your arrays. You don't need to sort them in the control.
component
this.getSelectedUserName = function (id, param) {
let name = ""; // should be array if you want to add unames to it
let userList = this.getUserList(param);
// what is `angular` here? And why loop here? Use ngFor in view.
angular.forEach(userList, function (value, key) {
if (value.userId == id){
name = value.name; // will be overwritten each time
// should be name.push(value.name); // but loop in view instead
}
});
// this.users = name; // for your original sorted version
this.users = userList;
}
In your view
<li *ngFor="let user of users; index as i;>
{{user.name}}
</li>

NodeJs note app delete function is not working?

I am building a Nodejs Note app and I am very new at this, so here the delete function doesn't work it, deletes everything from the array and I want to delete only title
There are two file app.js and note.js.
Here's the content of app.js file
if (command === "add") {
var note = notes.addNote(argv.title, argv.body);
if (note) {
console.log("Note created");
console.log("__");
console.log(`Title: ${note.title}`);
console.log(`Body: ${note.body}`);
} else {
console.log("The title has already exist")
}
} else if (command === "delete") {
var noteRemoved = notes.delNote(argv.title)
var message = noteRemoved ? "Note has been removed" : "Note not found";
console.log(message)
}
Here's the note.js content
var fetchNotes = function () {
try {
var noteString = fs.readFileSync("notes-data.json")
return JSON.parse(noteString);
} catch (e) {
return [];
}
};
var saveNotes = function (notes) {
fs.writeFileSync("notes-data.json", JSON.stringify(notes));
};
var addNote = function (title, body) {
var notes = fetchNotes();
var note = {
title,
body
};
var duplicateNotes = notes.filter(function (note) {
return note.title === title;
});
if (duplicateNotes.length === 0) {
notes.push(note);
saveNotes(notes);
return note;
};
}
var delNote = function (title) {
var notes = fetchNotes();
var filteredNotes = notes.filter(function (note) {
note.title !== title;
});
saveNotes(filteredNotes);
return notes.length !== filteredNotes.length
}
You miss return statement in delNote filter function
var filteredNotes = notes.filter(function (note) {
return note.title !== title;
});
or we can use es6 syntax:
const filteredNotes = notes.filter(note => note.title !== title);
You need to add return note.title !== title; in delNote function.

Filtering dates to within 7 days

I have a working date filter that accepts a date string like 2018-02-09T19:35:54+00:00 and orders events by date. I would like my filter to only push items in the next 7 days. I feel like I have a basic arithmetic error in my code.
function dashCalDateFilter() {
return function(collection, key) {
let output = [];
let keys = [];
let sevenDays = Date.now() + 604800000;
angular.forEach(collection, function(item) {
var ikey = item[key];
if (keys.indexOf(ikey) === -1) {
keys.push(ikey);
item['isFirst'] = true;
}
console.log(item.start_time);
if (Date.now() - Date.parse(item.start_time) < sevenDays){
output.push(item);
};
});
return output;
};
}
export default dashCalDateFilter;
My math was a bit off. Here is the working version
function dashCalDateFilter() {
return function(collection, key) {
let output = [];
let keys = [];
let sevenDays = 604800000;
angular.forEach(collection, function(item) {
var ikey = item[key];
if (keys.indexOf(ikey) === -1) {
keys.push(ikey);
item['isFirst'] = true;
}
if ((Date.parse(item.start_time) - Date.now()) < 604800000){
output.push(item);
} else {
console.log('in >7 days');
console.log(Date.parse(item.start_time) - Date.now());
};
});
return output;
};
}
export default dashCalDateFilter;

Does an angular.forEach create it's own scope?

My code has this HTML snippet:
<div ng-repeat="wf in wos.word.wordForms">
{{ wf }}
<textarea ng-change="wf.statusId = 2"
ng-model="wf.definition">
</textarea>
...
In a service I have this:
wordFormCheckAndUpdate = (): ng.IPromise<any> => {
var self = this;
var promises = [];
angular.forEach(self.word.wordForms, function (wf, key) {
if (wf.statusId == Status.Dirty) {
if (wf.createdDate) {
var updatePromise = self.wordFormUpdateSubmit(wf);
promises.push(updatePromise);
} else {
var addPromise = self.wordFormAddSubmit(wf);
promises.push(addPromise);
}
}
});
return self.$q.all(promises);
};
wordFormAddSubmit and wordFormUpdateSubmit modify the data in wf:
wf = angular.copy(response.data);
wf.statusId = 3;
wf.abc = "test"
When one of these functions is called it does not seem to change what is displayed above the textarea and the statusId still shows as 2 and "test" does not appear. Does anyone have any ideas what might be happening?
Update. Here are the two functions that are called:
wordFormAddSubmit = (wf: IWordForm): ng.IPromise<any> => {
var self = this;
return self.$http({
url: self.ac.dataServer + "/api/WordForm/Post",
method: "POST",
data: wf
})
.then(
(response: ng.IHttpPromiseCallbackArg<IWordForm>): any => {
wf = angular.copy(response.data);
self.$timeout(function () {
wf.statusId = 3;
wf.sourceId = 999;
}, 3);
},
(error: ng.IHttpPromiseCallbackArg<any>): any => {
self.ers.error(error);
return self.$q.reject(error);
});
}
wordFormUpdateSubmit = (wf: IWordForm): ng.IPromise<any> => {
var self = this;
return self.$http({
url: self.ac.dataServer + "/api/WordForm/Put",
method: "PUT",
data: wf
})
.then(
(response: ng.IHttpPromiseCallbackArg<IWordForm>): any => {
wf = angular.copy(response.data);
//$timeout(function () {
wf.statusId = 3;
//}, 1);
var a = wf;
var b = wf;
},
(error: ng.IHttpPromiseCallbackArg<any>): any => {
self.ers.error(error);
return self.$q.reject(error);
});
}

Resources