I have a database with two tables: 'GroupTable' & 'ItemTable'. GroupTable stores the group information such as group name etc. The ItemTable stores the item information as well as which group they belong to. Here's the thing, i am not using foreign key for some reason which i will not explain.
GroupTable: id, name, code
ItemTable: id, name, code, group
The ItemTable also stores the group, differentiated by group='-1'. So what i did was: Find all items in ItemTable with 'group = -1', get the codes of all the items, then filter the GroupTable and find all groups that has codes from the result. Because i need the group names of those groups which are in the ItemTable.
var grp = -1;
$.post("ItemTable/getItems", {group:grp}, function(result){
if(!result.error){
var count = result.data.length;
var data = result.data
var codes = new Array;
for (var i=0; i<count; i++) {
groups.push(data[i].code);
}
$.post("GroupTable/getItem", {code:codes}, function(result2) {
if (!result2.error){
var grpCount = result2.data.length;
var grpData = result2.data;
for (var i=0; i<grpCount; i++){
var name = grpData[i].name;
//DO SOMETHING WITH THE NAME HERE
}
}
}
}
}
Is there anyway i can achieve the same result using only a single post? Or am i looking at this wrongly and i should be editing my getItems function in my controller instead? Currently i am using 'TableItem.find(queryItem).exec()', how should i be writing my code to fit what i am trying to achiveve?
And yes let's assume for some reason i am not able to use foreign key, and that my code will ensure the 'code' is unique in GroupTable.
EDIT:
I am unable to copy and paste as i am working in an offline environment. I am using a MVC model, the code above are the codes for my view. As for the function 'getItems' in my controller, this is the code in my controller(summarized as i have to type this out)
getItems: function(req, res){
var id, name;
(typeof(req.params.id) === 'undefined') ? id=req.body.id : id=req.params.id;
(typeof(req.params.name) === 'undefined') ? name=req.body.name : name=req.params.name;
var queryItem = {
id: id,
name: name
};
// there is more than just id and name, as i did not type everything out
for (var propertyName in queryItem) {
if (queryItem[propertyName] == null){
delete queryItem[propertyName];
}
}
ItemTable.find(queryItem).exec(function(err, items){
if (err)
red.json({"error":err, data:null});
else
res.json({"error":null, data: items});
});
Related
I have 5 mysql tables that i need a variety of data from in several different scripts that all reference each other using an id's located in 1 or more column.
I need to create a master query that replicates the array structure exactly as it was imported from mysql AND ALSO needs error handling for each field before it writes to an array to determine if it needs to write the value to an array, or write it as null.
So far the script is looking like this:
const items = [];
// Items
for (let i = 0; i < gameItems.length; i++) {
if (gameItems[i].id) {
items.push({ id: gameItems[i].id });
} else {
items.push({ id: null });
}
if (gameItems[i].identifier) {
items.push({ identifier: if (gameItemParams[i].custom_name)
{
items.push({ custom_name: gameItemParams[i].custom_name });
}
else {
items.push({ custom_name: null }); }
}
}
The problem, or my lack of ability to figure out the logic on how to execute the code correctly, is that in order to attach multiple fields of data to the same row in an array the values must be comma separated.
Individual pushes like above add data to the next row instead of the same object which renders the array.length properly useless because there is a new row for every single field so instead of having 1 row with 10 pieces of data attached, i would have 10 rows each with 1 piece of data.
Is there a way to perform error handling for each field i need to call from the tables or is there another way to add data to the same object after a row has already been pushed.
This is how the newly created array must be structured:
https://puu.sh/E7ogn/61c3117d3b.png
This is how the array is currently being structured with individual pushes:
https://puu.sh/E7oh7/422541a70d.png
Maybe if it is possible to break in the middle of an array.push i can then add error handling in the push block but was unable to find if it can be done.
The problem is that you are pushing an object every time. Instead of that, you need to create an object with all of fields and then push it to the array.
Other problem of your code is that you can use an if statement into a assigment statement. You need to use a conditional operator to do that or extract this conditional from the assigment.
const items = [];
// Items
for (let i = 0; i < gameItems.length; i++) {
var object = {};
if (gameItems[i].id) {
object.id = gameItems[i].id;
}
else {
object.id = null;
}
if (gameItems[i].identifier) {
object.identifier = (gameItemParams[i].custom_name) ? items.push({ custom_name: gameItemParams[i].custom_name }); : items.push({ custom_name: null });
}
items.push(object);
}
As per the data mentioned in https://puu.sh/E7oh7/422541a70d.png.
You have data like
gameItems=[{id:0}, {identifier:"master-ball"}, {category_id:34}, {"custom_name":"Master Ball"}];
I suggest that instead of making items as an array, Please create temporary object item and then push it to items.
let items = [];
let item = {
id:null,
identifier: null,
custom_name: null
};
for (let i = 0; i < gameItems.length; i++) {
if (gameItems[i].id !== undefined) {
item.id = gameItems[i].id;
}
if (gameItems[i].identifier !== undefined) {
item.identifier = gameItems[i].identifier;
}
if (gameItems[i].custom_name !== undefined) {
item.custom_name = gameItems[i].custom_name;
}
}
items.push(item);
I'm currently facing a difficulty in my codes.
First i have an array of objects like this [{Id:1, Name:"AML", allowedToView:"1,2"}, {Id:2, Name:"Res", allowedToView:"1"}...] which came from my service
I assign it in variable $scope.listofResource
Then inside of one of my objects I have that allowedToView key which is a collection of Id's of users that I separate by comma.
Then I have this code...
Javascript
$scope.listofResource = msg.data
for (var i = 0; i < msg.data.length; i++) {
First I run a for loop so I can separate the Id's of every user in allowedToView key
var allowed = msg.data[i].allowedToView.split(",");
var x = [];
Then I create a variable x so I can push a new object to it with a keys of allowedId that basically the Id of the users and resId which is the Id of the resource
for (var a = 0; a < allowed.length; a++) {
x.push({ allowedId: allowed[a], resId: msg.data[i].Id });
}
Then I put it in Promise.all because I have to get the Name of that "allowed users" base on their Id's using a service
Promise.all(x.map(function (prop) {
var d = {
allowedId: parseInt(prop.allowedId)
}
return ResourceService.getAllowedUsers(d).then(function (msg1) {
msg1.data[0].resId = prop.resId;
Here it returns the Id and Name of the allowed user. I have to insert the resId so it can pass to the return object and it will be displayed in .then() below
return msg1.data[0]
});
})).then(function (result) {
I got the result that I want but here is now my problem
angular.forEach(result, function (val) {
angular.forEach($scope.listofResource, function (vv) {
vv.allowedToView1 = [];
if (val.resId === vv.Id) {
vv.allowedToView1.push(val);
I want to update $scope.listofResource.allowedToView1 which should hold an array of objects and it is basically the info of the allowed users. But whenever I push a value here vv.allowedToView1.push(val); It always updates the last object of the array.
}
})
})
});
}
So the result of my code is always like this
[{Id:1, Name:"AML", allowedToView:"1,2", allowedToView:[]}, {Id:2, Name:"Res", allowedToView:"1", allowedToView:[{Id:1, Name:" John Doe"}]}...]
The first result is always blank. Can anyone help me?
Here is the plunker of it... Plunkr
Link to the solution - Plunkr
for (var i = 0; i < msg.length; i++) {
var allowed = msg[i].allowedToView.split(",");
msg[i].allowedToView1 = [];
var x = [];
Like Aleksey Solovey correctly pointed out, the initialization of the allowedToView1 array is happening at the wrong place. It should be shifted to a place where it is called once for the msg. I've shifted it to after allowedToView.split in the first loop as that seemed a appropriate location to initialize it.
i am trying to query a class of users which contains a relation column called "blocking" which contains a list of user objects from the same class
when i try to query all users i would like to query which is not present in this relation column
i did the following
var currentUser = Parse.User.current();
var relation = currentUser.relation('blocking')
query.doesNotExist(relation);
query.find().then((users)=>{
for (let i = 0; i < users.length; i++) {
let object = users[i];
console.log(object)
}
}, (error) => {
console.log(error);
});
but it did not work
any help will be appreciated
I managed to do it myself
at first i query the relation and store a list of blocked ids in an array
var currentUser = Parse.User.current();
var relation = currentUser.relation("blocking");
relation.query().find().then(blockedusers=>{
var blockedIds = []
for (var i = 0; i<blockedusers.length; i++){
blockedIds.push(blockedusers[i].id)
}
})
after that i moved the whole query inside the relation find and do (not contained in) this array like the following
query.notContainedIn("objectId", blockedIds)
that solved my problem
thanks
I am working on a shopping cart application were users can click an Add to Cart button that will then add the specific item to local storage. When the user is adding a product to their shopping cart I need to be able to check to see if that specific item/value/product already exists in local storage. If it does, I need to increase only the count of that item/value/product by 1. If not, I need to add an entirely new item/value/product to local storage with a count of 1.
How can I find if an item already exists in local storage and compare it to the id of the current product that a user is attempting to add to their cart? My first few attempts failed miserably and have yet to find anything online that is helping with this issue. Is there a better way of going about this? Any assistance is appreciated. Even a good link to a good page would be extremely helpful.
Below is the code I have to attempt in checking for if the productid being added matches any of the productids in local storage. Basically if the productId that is being added matches the productId of an item in local storage simply add 1 to the quantity.
var retrieverObject = localStorage.getItem('Products');
var retrieveObject = JSON.parse(retrieverObject);
var data = {};
var productId = currentNode.name;
var product = currentNode;
data.productPrice = product.parentNode.previousSibling.previousSibling.id;
data.productId = productId;
var length = retrieveObject.length;
console.log(length);
for(var i = 0; i<length; i++){
if(retrieveObject[i].productId == data.productId){
var quantity = retrieveObject[i].quantity;
retrieveObject.push({"productPrice": data.productPrice, "productId": data.productId, "quantity": quantity++});
}else{
retrieveObject.push({"productPrice": data.productPrice, "productId": data.productId, "quantity": 1});
}
}
console.log(retrieveObject);
localStorage.setItem('Products', JSON.stringify(retrieveObject));
var retrievedObject = localStorage.getItem('Products');
var obj = JSON.parse(retrieverObject);
var len = obj.length;
console.log(len);
for(var i=0; i<len;i++){
console.log(obj[i]['productPrice']+", "+obj[i]['productId']);
}
}
}
There are a few issues. First, I am not entirely certain that the productId of the retrieved object is being compared to the one that is being added. Secondly, the for(var i = 0; i<length; i++){} definitely does not seem to be doing what was expected and is multiplying the number of items being added by 2. Thirdly, which may relate to the second issue, the retrieveObject.push() is not updating the quantity of the product but is adding an entire new entry to local storage. The given answers did not seem to be working for me before so this is what I have been working on. Any new answers or general help would be great.
PT 2. : So I am having an issue with the first entry into the local storage. Without noting that when there is nothing in local storage and you make a call to get the items in it, it returns null or undefined. So currently I have it set up like this:
if(localStorage.getItem("Products") === null || localStorage.getItem("Products") === undefined){
var data = {};
var productId = currentNode.name;
var product = currentNode;
data.productPrice = product.parentNode.previousSibling.previousSibling.id;
data.productId = productId;
var obj = [];
obj = obj[data.productId] = {
productPrice: data.productPrice,
count: 1
};
console.log(obj);
localStorage.setItem('Products', JSON.stringify(obj));
}
else{
var retrieverObject = localStorage.getItem('Products');
var retrieveObject = JSON.parse(retrieverObject);
var data = {};
var productId = currentNode.name;
var product = currentNode;
data.productPrice = product.parentNode.previousSibling.previousSibling.id;
data.productId = productId;
if(retrieveObject[data.productId]){
retrieveObject[data.productId].count++;
}else{
retrieveObject[data.productId] = {
productPrice: data.productPrice,
count: 1
};
}
console.log(retrieveObject);
localStorage.setItem('Products', JSON.stringify(retrieveObject));
}
This creates a first entry in local storage that looks like this : {"productPrice":"78.34","count":1}, and then when adding others looks like this: {"productPrice":"78.34","count":1,"rJUg4uiGl":{"productPrice":"78.34","count":3}} and works perfectly fine. The issue is getting the first entry to b formatted properly. When I change the code in the first if statement like so:
var obj = [];
obj[data.productId] = {
productPrice: data.productPrice,
count: 1
}
I get an empty [] in local storage but when I console.log the obj it is in the proper format. [rJUg4uiGl: Object]. I have been stuck on this and haven't been able to get it working. Again, any help would be really appreciated.
Once you have your data structure in obj, I would suggest using a dictionary with product IDs as keys.
To add the order or whatever, where you have:
obj.push({"productPrice": data.productPrice, "productId": data.productId});
Use:
if (obj[data.productId]) { // if the entry exists,
// increment the count
obj[data.productId].count++;
} else { // if it doesn't,
// add a new entry with count = 1
obj[data.productId] = {
productPrice: data.productPrice,
count: 1
};
}
Here is a complete function, including localStorage handling:
function addToCart(productID, productPrice) {
// get the current cart, or an empty object if null
var cart = JSON.parse(localStorage.getItem("Products")) || {};
// update the cart by adding an entry or incrementing an existing one
if (cart[productId]) {
cart[productId].count++;
} else {
cart[productId] = {
productPrice, // shorthand for `productPrice: productPrice,`
count: 1
};
}
// put the result back in localStorage
localStorage.setItem("Products", JSON.stringify(cart));
}
The solution above is preferable because you can check for a productId without looping through the whole list. If you really want to keep your current data structure of an array of objects, you could update it like this:
var length = retrieveObject.length;
console.log(length);
for (var i = 0; i < length; i++) {
if (retrieveObject[i].productId == data.productId) {
retrieveObject[i].quantity++; // update the entry in the array
} else {
retrieveObject.push({
productPrice: data.productPrice,
productId: data.productId,
quantity: 1
});
}
}
Note that you shouldn't push a new entry into the array; just update the existing one.
Just use localstorage.getItem; it returns null if the key doesn't already exist.
Assuming you are using localStorage node package you could do
if (localStorage.getItem('Products') !== null) {
localStorage.setItem('Products', JSON.stringify(obj));
}
Here is your reference:
https://www.npmjs.com/package/localStorage
Regards
Update:
Searching within your objet is a different story... so you want to check if the Product id is there then you can search for it using lodash
var _ = require('lodash');
// the rest of your code to get the data.productId set
if (localStorage.getItem('Products') !== null) {
var arrayOfProducts = localStorage.getItem('Products');
var existingProducts = _.filter(arrayOfProducts, function (product) { return product.productId === data.productId });
if (existingProducts.length > 0) {
// product found, do your logic
}
}
Here's lodash info https://www.npmjs.com/package/lodash
The other option is using a dictionary and having the productId as key and then using Object.keys to search for it... I've offered an approach that does not change your json structure.
I have some problem in crating an autocomplete search box. I have a mongodb collection in which there are photos object with name, description, path and so on. Now, I created a route /searchbox, where the box is displayed in the browser. Every time that the user press a key, a get request to the route /autocomplete/:query is made. The autocomplete route will search in the collection for all the objects where the name, the description or the keywords fields starts with the give query. Then it return a json object containing all the strings that will be put into a datalist in the view. The problem is that I can't create that json array, I tried to create a json object with a field containing an array, and at every iteration on the found array returned by the find function, I get the field name and push it into the array, but nothing is added... here my code:
exports.autoComplete = function(req, res) {
var PhotoAlbum = db.model('PhotoAlbum', schemas.PhotoAlbumSchema);
var regexp = "^"+req.params.query;
var suggestions = {suggestion: []};
var strings = "";
var arrayStrings = [];
PhotoAlbum.find({name: new RegExp(regexp,"i")}, function(err, found) {
if(err) throw handleError(err);
for(obj in found) {
var name = found[obj].name;
suggestions.suggestion.push(name);
strings += name + "|";
}
});
}
Thank you
That looks like Mongoosejs with MongoDB.
IF it is, in that case, its not returning an object at "found". "found" is a collection that is an array already in which you would iterate through it like so:
for(var i = 0; i < found.length; i++) {
console.log(found[i]);
// your code
}