I'm using Ember JS and i don't know if my approach to achieve the thing i want is true or maybe there is another way. If there is a better way please tell me.
Now I have a model named "visit" among the data it stores is the "time" of the visit
Now the time is set through a hard-coded service loop in select tag.
I want the user to select the date of the visit "a query is sent to the database with the selected date to get the visits in that date" then I want to compare the time in the results of the query with the array provided in my service and remove the similar one's. Ergo the pre-selected time isn't available.
I tried to loop in the template for the service data then another loop for the "visit" query and added an "if" statement in the class of the time display to add "disabled" if the two values equal each other.
The problem here is that the loop shows me the data twice now or maybe thrice affected by the results found in the query.
I think there is another approach by simply handling the data in the "visit" query to simply remove the matched data from the service and the results, but I'm not sure how to do so.
Here is my template
{{#each formData.time as |time|}}
{{#each disabledTime as |disabled|}}
{{#if (eq disabled.value time.value)}}
<button class="disabled">{{time.time}}</button>
{{else}}
<button {{action 'addTime' time}} class="btn-success">{{time.time}}</button>
{{/if}}
{{/each}}
{{/each}}
And Here is my controller
formData : Ember.inject.service(),
store : Ember.inject.service(),
disabledTime : Ember.computed("model.issueDate", function(){
return this.get('store').query('visit', { where : { issueDate : this.get('model.issueDate') } } );
}),
Is there a better way to handle the data in the "disabledTime" so I take the data from the service "formData.time" and remove the similar data then return the data that doesn't match. Because this way it looks simpler and I can make the loop in the template through a "select" tag instead of the buttons.
If your query return an array, and your FormatDate.time too, what about setDiff ?
you would have something like :
formData: Ember.inject.service(),
store: Ember.inject.service(),
disabledTime: Ember.computed("model.issueDate", function(){
return this.get('store').query('visit', { where : { issueDate : this.get('model.issueDate') } } );
}),
availableTime: Ember.setDiff('formData.times', 'disabledTime')
and use it in your template
<select>
{{#each availableTimes as |time|}}
<option value=time.time>{{time.time}}</option>
{{/each}}
</select>
As i understand, you have two arrays of objects, which share a property value. You now want to filter the formData.time list to objects with a value not present in the disabledTime list.
Instead of looping always completely over the second list, for each object in the first list, you could filter formData.time beforehand:
// computed based on contents in formData.time and disabledTime
filteredTimes: Ember.computed('{disabledTime.[],formData.time.[]}', function() {
let disabled = Ember.get(this, 'disabledTimes');
// return a filtered formData.time
return Ember.get(this, 'formData.time').filter(time => {
let value = Ember.get(time, 'value');
// inclued only if value not present in disabledTime list
return !disabled.isAny('value', value));
});
})
This assumes that if an object exists only in disabledItem it can be ignored. If not so, you'd have to merge, not filter the lists (i.e. return a new list with disabled flag).
Related
I have a list, and I need to delete an element to be deleted.
The delete button works in that it sends the delete request to the server. However, a page refresh is needed to have it delete from the front end.
I want it deleted after the delete button is clicked.
I could simply set a boolean on the front end as follows:
render && <ComponentToDelete />
and change render from true to false.
Is this the preferred way or is there a best practice or more standard way.
I'm simply doing a delete on an item as part of CRUD operations.
I'm not sure if this is relevant:
https://reactjs.org/docs/react-dom.html#unmountcomponentatnode
Also, per comment here is how the list is generated:
let render;
if(new_articles.length > 1){
render = new_articles.map((val, index) => {
return <ComponentArticle key={index} data={val}/>;
});
}
return render;
google search here
As in example above, you just need to remove item from new_articles. Let's say the deleted id is deleted_id, You can remove that item from array by trying the following snippet
new_articles.filter((article) => article_id !== deleted_id);
You should be using new_articles array as state value.
If you make any change to the array, render will update UI automatically.
So after you send delete request to server and get successful response, you can change the new_articles array to reflect the deleting.
You can use one of Javascript functions like fliter or splice with deleted index.
I got 2 array, one for states and another one for countries. I want to display the country name of the state. So, I'm using Laravel 5.7 for the backend and I get data using this for the countries Country::get(); and Vue.js recieve the array like this:
countries:Array(4)
0:created_at:(...)
deleted_at:(...)
id:(...)
name:(...)
shortName:(...)
updated_at:(...)
1:{…}
2:{…}
3:{…}
I do the same for the state as the country. State::get(); and vue recieve this:
states:Array(1)
0:country_id:(...)
created_at:(...)
deleted_at:(...)
id:(...)
name:(...)
shortName:(...)
updated_at:(...)
When I display the data into the table using v-for:
<tbody>
<tr v-for="state in data.states">
<td>{{SOMTHING TO DISPLAY COUNTRY NAME}}</td>
<td>{{state.name}}</td>
<td></td>
</tr>
</tbody>
At the first cell, I tried to do {{data.countries[state.country_id]['name']}} but it failed. Instead it display another country in the array where the key correspond to the country_id I gave.
I know that I can solve my problem by doing this State::with('country')->get(); and then into my vue component doing this state.country.name, but since I already send every country, I'm looking for another way to perform it.
Any idea?
You want to JOINyour country data to your state data using state.country_id mapped to country.id.
Map your countries by ID
const cmap = {} // in your vue.data
countries.forEach(it=>cmap[it.id] = it)
Or use reduce
const cmap = countries.reduce((acc,cur)=>{acc[cur.id]=cur; return acc},{})
Put the map in a computed property so it is calculated one time on demand.
countryMap(){
return this.countries.reduce((acc,cur)=>{acc[cur.id]=cur; return acc},{})
}
Create a lookup method
getCountryName(state){
return this.countryMap[state.country_id].name
}
Use it in a template like this
<div>{{getCountryName(state)}}</div>
You don't need a lookup method, but if you are using Vue, it makes sense to break things up. this.countryMap[state.country_id].name is a bit messy in a template.
Since I'm using map with many object, I just changed my code in a way that I don't need to repeat myself everytime.
Since now, the code is a method instead of a computed property.
dataMap: function($model) {
return this.data[$model].reduce((acc,cur)=>{acc[cur.id]=cur; return acc},{});
},
I use it this way into the component:
{{dataMap('countries')[dealer.country_id].name}}
And my data look like this:
export default {
data() {
return {
data: {
countries:{...},
states:{...},
cities:{...},
groups:{...},
dealers:{...},
users:{...},
},
}
},
So that way I can use the dataMap method for anything found into data array without having to recode a new map computed property. I just have to do this:
{{dataMap('users')[something.user_id].field}}
{{dataMap('groups')[something.group_id].field}}
This is my first app project using Google Cloud Functions & Firebase. I'm trying to find away to get a single value of the array that I'm returning and compare it to a set variable and if it matches, update another child's value in that same account.
My App users can add records to the database under their login/user_id that is stored in the database. I'm trying to get a list of the "RecordName" that is a child under that login/user_id that every user has stored in their account.
So basically every "RecordName" in the entire database. When I want to run specials for those records, I need to match the name of that record to the name of the record I have on special and if there is a match, update another child value under that user's account ("special" = true.). This way, when they load their app next time, I have it highlighting that record so they know it's on special.
When I use..
const ref = admin.database().ref(`/store`);
...with the following code...
ref.on('value', function(snapshot) {
// puts ALL items of the object into array using function ..
console.log(snapshotToArray(snapshot));
});
... and the function...
function snapshotToArray(snapshot) {
var returnArr = [];
snapshot.forEach(function(childSnapshot) {
var item = childSnapshot.val();
item.key = childSnapshot.key;
returnArr.push(item);
});
return returnArr;
};
... I get the entire array just as it is in the database:
-store
-{ones_users_id}
-recordname: value1
-special: false
-{anothers_users_id}
-recordname: value2
-special: false
ect. ect.
If my record on special is called, "Newbie Record", what would be the best way to take out every individual value for the key: "recordname" from the array, compare each one to var = "Newbie Record" and if they match, update the value of the key: "special" to be true?
I'm new to JSON and NodeJS, I've been searching on here for answers and can't find exactly what I'm looking for. Your feedback would be very helpful.
It sounds like you're looking to query your database for nodes that have "recordname": "Newbie Record" and update them.
An easy way to do this:
const ref = admin.database().ref(`/store`);
const query = ref.orderByChild("recordname").equalTo("Newbie Record");
query.once('value', function(snapshot) {
snapshot.forEach(function(child) {
child.ref.update({ special: true })
});
});
Main differences with your code:
We now use a query to read just the nodes that we want to modify.
We now use once() to read the data only once.
We loop over the children of the snapshot, since a query may result in multiple nodes.
We use the reference of each child and then update its special property.
I recommend reading a bit more about Firebase queries in the documentation.
I have a template.
{{#each dbModel in model}}
<h2>Database Name : {{dbModel.databaseName}}</h2>
<h3>Select Table:
{{view Ember.Select
content=dbModel.tables
optionValuePath="content.tableName"
optionLabelPath="content.tableName"
valueBinding = "dbModel.selectedTable"
selectBinding = "dbModel.selectedTable"
}}
</h3>
<h2>Selected Table is : {{dbModel.selectedTable}}</h2>
{{#each table in dbModel.tables}}
{{dbModel.selectedTable}}
{{#matchTable table.tableName dbModel.selectedTable}}
//Get fields is selected table match with table name
{{/matchTable}}
{{/each}}
Now In the matchTable helper I am getting value of table.tableName but for dbModel.selectedTable is undefined.
dbModel.selectedTable is not part of actual model, I have added this to controller as follows.
App.DatabaseController = Ember.ArrayController.extend({
selectedTable:[],
actions: {
cancel: function () {
// something
}
}
});
When I change the value of select it automatically updates the information in <h2> tag. So it means that the value is setting and got bind properly. But for helper when I try to pass it it simply shows undefined. I searched and found that can use ../dbModel.selectedTable. Still it is undefined. Anyone please guide.
What is the way to pass the parent to the helper in each loop?
Your #each loop drops you into the scope of the tables array. ../ places you in the scope of the dbModel object. To access selectedTable within the loop, use ../selectedTable
I'm fetching a list of records from App.Resource.find() This is working fine.
For each row of data there is a drop down box with fixed values. When a change is made to a drop down box I'd like to issue a POST or PUT request back to the server to update that row with the newly selected value from the drop down.
I am having trouble with two things:
How can I get the ID and selected value of the dropdown in my model or controller
How can I take those values and issue a request to the server. Is there App.Resource.update...?
I have a jsBin of the working example with local data: http://jsbin.com/OcAyoYo/84/edit
Ok, here's one approach to get the selected value, let's put things where they should go, ok, first of all, let's create a controller which is going to decorate your Response records, you mixed names, you're using Post, so, I'll use that name, here is the controller:
App.PostController = Ember.ObjectController.extend({
selectedChanged: function() {
//here, you have access to the selected value with this:
// this.get('selected')
//And also, this controller represents you object rendered on the screen,
//so, you can change it here if you want like this:
//this.set('whataverPropertyYouWantToChange', 'newValue');
//then you can save this record(send the request to the server) by just doing this:
//this.save(); this will make a request to the server
}.observes('selected')
});
then, in order to use that controller, change the loop where you render the records, to this:
{{#each model itemController="post"}}
<tr>
<td>{{author}}</td>
<td>{{book}}</td>
<td>
{{view Ember.Select
contentBinding= 'App.names.content'
selectionBinding='selected'}}
</td>
</tr>
{{/each}}
just be careful, in PostController, the observer will be fired even if the 'selected' property has null values, you need to verify if it is not null.