I have this code in my router:
category: (id) ->
alert id
filteredProducts = new App.Collections.Products(#productsCollection.where({category_id: id}))
#productsView.renderResults(filteredProducts)
The alert id call works properly (e.g. app.com/categories/6 > alerts "6") and when I change the id in the where function to an actual number the products collection filters properly like so:
filteredProducts = new App.Collections.Products(#productsCollection.where({designer_id: 6}))
But when I set the designer_id: id the where loop return an empty collection.
My foreign key category_id was a number not a string. The answer is:
filteredProducts = new App.Collections.Products(#productsCollection.where({category_id: parseInt(id)}))
Related
I am getting a book list from database and is stored in a state variable Book list also has book price field
const [books, setBooks]=useState([])
setBooks(data)
Each books object in the array has properties like BookName, Author , Price, Discount
I have rendered a html table like follows
return ( <div>
{books.map((x,i) => ( <tr>
<td>x.bookName</td>
<td>x.price</td>
<td><MyCustomTextInput onChange={e => handleChange(e, x.id)} value={x.discount}></MyCustomTextInput></td>
<tr></div>);
the sample code for MyCustomTextInput is as follows
function MyCustomTextInput(props)
{ return (<div><TextInput></TextInput> </div>)
} exports default MyCustomTextInput
The code where I update the price for corresponding object in "books" array is as follows
function handleChange(x,id){
var obj = books[id];
obj.price = obj.price - e.target.value; //I am correctly getting discount in e.target.value
}
Every thing works properly except the price after discount is not reflecting on the UI. though its getting updated properly in the array but not reflecting on the UI.
any help....
Experts -
This is setting a value:
function handleChange(x, id){
var obj = books[id];
obj.price = obj.price - e.target.value;
}
But it's not updating state. The main rule to follow here is to never mutate state directly. The result of bending that rule here is that this update never tells React to re-render the component. And any re-render triggered anywhere else is going to clobber the value you updated here since state was never updated.
You need to call setBooks to update the state. For example:
function handleChange(x, id){
setBooks(books.map(b =>
b.id === id ? { ...b, price: b.price - parseFloat(e.target.value) } : b
));
}
What's essentially happening here is that you take the existing array in state and use .map() to project it to a new array. In that projection you look for the record with the matching id and create the new version of that record, all other records are projected as-is. This new array (the result of .map()) is then set as the new updated state.
There are of course other ways to construct the new array. You could grab the array element and update it the way you already are and then combine it with a spread of the result of a .filter to build the new array. Any construction which makes sense to you would work fine. The main point is that you need to construct a new array and set that as the new state value.
This will trigger React to re-render the component and the newly updated state will be reflected in the render.
You need to setBooks to update state books.
function handleChange(x, id) {
setBooks(
books.map((item) =>
item.id === id ? { ...item, price: item.price - parseFloat(e.target.value) } : item,
),
);
}
To achieve that, you need to call setBooks after changing the price within handleChange method to re-render the component with the newly updated state.
It's simply like the following:
function handleChange(x,id){
var obj = books[id];
obj.price = obj.price - e.target.value; //I am correctly getting discount in e.target.value
setBooks([...books]);
}
I am trying to retrieve the user's key based on the child's email, which is student#memail.com in this case. I have tried many ways but could not get a way to retrieve the key of the record. I want to retrieve the value KKTxEMxrAYVSdtr0K1NH , below is the snapshot of the database
Currently, if((childSnap.val().role) == "student") { returns me student and snap.key() returns me "User". How do I retrieve KTxEMxrAYVSdtr0K1NH ?
What method are you using to retrieve the node? If you are using on "child_added" then you can use: childSnap.key
If you are using on "value" then your references is the keys in the response object. So you can use:
for (var key in childSnap.val()) {
console.log(key)
}
or
childSnap.forEach(...)
Here is an example to clearify (check the console):
https://jsfiddle.net/qrLvbok4/1/
There is a difference between value and child_added, check the list for child events section: https://firebase.google.com/docs/database/web/lists-of-data
var ref = firebase.database().ref('Users');
ref.on('child_added', function(snap) {
// You can retrieve the parent key by calling snap.key
console.log(snap.key);
});
UPDATE (Get parent key by email):
var ref = firebase.database().ref('Users').orderByChild('email').startAt('student#memail.com').endAt('student#memail.com');
ref.once('value', function(snap) {
console.log(Object.keys(snap.val())[0]);
});
Okay so i have the following object:
$scope.search = {};
this allows me to search through the following elements:
<div class="col-md-12" ng-repeat="question in questions | filter:search:strict">
Now one of the things i can do is to set a variable called category_id which then filters the category_id of each item:
$scope.search.category_id = selected.id;
However there is a problem. once i try to reset it AKA call $scope.search.category_id = null
All result disapear.
So it seem it is searching for categories where id = null which is false in every case.
So my question is how do i reset it then?
You should delete the property from the object rather than setting it to null. That will remove it from being listed in the search criteria.
delete $scope.search.category_id
You can see how this is different from setting it to null below
var a = { hello: 5 }
console.log(a, Object.keys(a)) // Object {hello: 5} ['hello']
a.hello = null
console.log(a, Object.keys(a)) // Object {hello: null} ['hello']
delete a.hello
console.log(a, Object.keys(a)) // Object {} []
On my backend, I have a nested categories structure like this:
Category
--------
id
parent_id
name
That I load completely into $scope.categories as a single dimension array.
On screen, I want to show one dropdown per level, showing the correspondent path. For example, if the path is cars/sedan/ford/taurus, I want to show four dropdowns:
Cars v Sedans v Ford v Taurus v
Whenever a dropdown is changed, the ones to the right should be deleted, and the immediate one populated with all child categories whose parent is the one I just selected. Regular stuff.
I also created a category_path array that contains each category_id in the path to the product category: [null, category_id, category_id, category_id].
And then I did this:
<select
ng-repeat="item in category_path"
ng-model="selected_category[$index]"
ng-options="category.name for category in (categories | filter : { parent_id: item } : true ) track by category.id "
ng-change="select_category(selected_category[$index], $index)"
></select>
On my controller:
$scope.select_category = function ( selected_category, index ) {
if ( $filter('filter') ($scope.categories, { parent_id: selected_category.id }, true).length ) {
if ( $scope.category_path[index+1] != undefined ) {
$scope.category_path = $scope.category_path.slice(0, index+1);
$scope.category_path[index+1] = selected_category.id;
} else {
$scope.category_path.push( selected_category.id );
}
} else {
$scope.product.category_id = selected_category.id;
}
}
This works like charm, except for the fact that I can't populate the default values for each dropdown, based on the current product category_path array.
I tried:
ng-init="select_category[$index] = category_path[$index]"
without success. Ideas?
Your category_path array holds different values than the model, i.e. the selected_category array. The latter seems to hold JSON strings while the former holds a single value (for the id key).
To make the default values work, insert the full JSON objects into the model array.
How to set a default id to 0 for the tags which is not from the list ?
[DEMO LINK][1]
LINK
In the above e.g if we select from existing, then it comes with id (1 or 2 or 3), but if add new Tag and press enter then the id becomes as text, i want id to set as o for new tag OR not from the list.
How to do that?
CreateSearchChoice should be what you are looking for
here is a similar SO i asked a while ago select2 createSearchChoice id from post
createSearchChoice: function (term, data) {
if ($(data).filter(function () {
return this.text.localeCompare(term) === 0;
}).length === 0) {
// if not found in current list
// return {id:term, text:term}
return {
id: term,
text: $.trim(term) + ' (new tag)'
};
},
Note i am setting the id to new text term, you could set it to a concatenated value like -1/term, then parse it out later, but term must be included in the ID for this solution
then on the change event, i determine whether the id is numeric (exists already). if its not numeric (added in the createsearchchoice) I go through my process of posting to the database of tags
.on("change", function(e) {
if (e.added) { //is it added from select2
if (isNumeric(e.added.id)){ //did it already exist or createsearchchoice
add(e.added.id); //it already existed, just add it to the tag list
} else { //id was created on the fly, post to the database and return a tag id
$.post('handlers/tags.ashx', {
operation:"select2createtag",
//because its not numeric, we know id = new tag text
text: $.trim(e.added.id)} ,
function(data){
//set the added id to the id you just returned from sql
e.added.id = data.id;
//...do something else, like then add the new tag to the item
});
};
};
if you dont want to post to ajax, have your server-side evaluate your input items, and any tags that are non-numeric for id , follow the same idea above
I updated your Plunker here