Hopefully, a simple question and must have a simple answer but i have wasted almost 3hrs in getting out of this issue.
I have a user model. I want to load the first user from DB and show it on first page load.
What i am trying to use is:
in my ArrayController,
init: function(){
var user = App.User.find(1)
console.log(user);
this.set('defualtUser',user.get('name'))
}
But i cant get the name of user.
Here is the output of user in console, which indicates that data is being loaded but i can't just get it to use.
Class
__ember1367188634172: "ember270"
__ember1367188634172_meta: Meta
_changesToSync: Object
_data: Object
attributes: Object
***name: "Cafe Alpino"***
__proto__: Object
belongsTo: Object
hasMany: Object
id: null
__proto__: Object
See the name: "Cafe Alpino", i just want to display this name.
Any help???
BTW, i am a newbie with EmberJS
I think the problem here is asynchronousy. This line: var user = App.User.find(1) will result in a user record that is not loaded yet; its properties aren't set until the AJAX call returns in the background. Therefore, user.get('name') will be empty.
There are probably a few ways to solve this. I haven't used Ember Data too much (since it's not very solid at the moment), but according to the docmentation, there should be a didLoad event that you can use:
init: function() {
var user = App.User.find(1);
var _this = this;
user.on('didLoad', function() {
_this.set('defaultUser', user.get('name'));
});
}
Give it a try! Let me know if it doesn't work out.
Related
I'm a total beginner working through an entry-level university course on data handling. I've been tasked with building a simple database app that the user can add movies to and then mark them "watched". I have a "watch a movie" function (source below) that needs to prompt the user for the name of the movie and then mark that particular movie as "watched". The function receives a movie collection from a database as its single parameter, and the collection only contains the name and watched status for each movie.
Now what happens is the update method on the last line doesn't do anything, and I can't figure out why. I've tested it by including a print command right after the update command, but the document is unchanged. I even tried updating the name of the movie at the same time, but no change.
Any ideas?
watch(collection) async {
print('Name of the movie?');
var name = stdin.readLineSync();
var terms = Query(filter: ValueFilter({'name': name}));
var results = await collection.search(query: terms);
var documents = results.snapshots;
for (var i = 0; i < documents.length; i++) {
var data = documents[i].data;
var document = documents[i].document;
document.update(data: {'name': data['name'], 'watched': true});
}
}
OK, so I had help and managed to solve this. I don't know why, but the ValueFilter needed a MapFilter around it, i.e.
var haku = Query(filter: MapFilter({'nimi': ValueFilter(nimi)}));
It works now, but if anyone could explain why, I'd appreciate it. :D
I just ran into a problem where I am not sure how to solve.
Background: I've got an App with two views:
1st one to input a number,
2nd one to see the details.
After the view switched to the detail view, I would call the bindElement() to get my data from the backend.
_onRoutePatternMatched: function(oEvent) {
// ...
this.getView().bindElement({
path: "/EntitySet('" + id+ "')"
});
},
Problem is that the ID is quite often the same, hence, the method will call the backend only if the ID is different from the last call.
So I tried to solve the problem by using the following:
this.getView().getModel().read("/EntitySet('" + id+ "')",{
success: function(oData, response) {
that.getView().setModel(oData, "");
}
});
By this, the data is always up to date. But now the binding is a bit different.
Binding with bindElement():
{
"id": "1234",
"propety1": "abc",
// ...
}
Binding with setModel() and id = 1234:
{
"EntitySet('1234')": {
"id": "1234",
"propety1": "abc",
// ...
}
}
For the first way, my binding looked like this:
<ObjectHeader title="{id}">
Now, it would have to look like this:
<ObjectHeader title="{/EntitySet('1234')/id}">
And here I have a problem, because the value of id (in this case 1234) will always be different and so the binding won't work. I can't bind directly to the ObjectHeader, because I will need some properties from the model later. That is the reason I am binding to the view so that all that remain available.
My idea was to edit the binding inside the success method of the read method. I would like to delete the surrounding element. Do you have an idea, how to do this? Or even a simpler/better idea to solve my pity?
Edit:
I forgot to mention the refresh method. This would be possible, but where do I have to put it? I don't want to call the backend twice.
Simply call the API myODataModel.invalidateEntry(<key>) before binding the context in order to retrieve the latest data.
// after $metadata loaded..
const model = this.getOwnerComponent().getModel("odata");
const key = model.createKey(/*...*/) //See https://stackoverflow.com/a/47016070/5846045
model.invalidateEntry(key); // <-- before binding
this.getView().bindElement({
path: "odata>/" + key,
// ...
});
From https://embed.plnkr.co/b0bXJK?show=controller/Detail.controller.js,preview
invalidateEntrydoc
Invalidate a single entry in the model data.
Mark the selected entry in the model cache as invalid. Next time a context binding or list binding is done, the entry will be detected as invalid and will be refreshed from the server.
I am just starting out with Firebase and have managed to send data to a Firebase Realtime Database. The problem is that some times it works and sometimes not. I am struggling to understand why.
Here is a code snippet
var pq_data = jsPsych.data.get().values();
for (var ix= 0; ix < pq_data.length; ix++){
var object=pq_data[ix];
var pq_boo = pq_database.ref(subj_id +ix.toString()+'/').update(object)
}
As I say this works sometimes but not always and I understand that it may have something to do with the code completing before the write operations have(?)
I have read but do not clearly understand advice about onCompletion and I am still in the dark. I need to make sure each object is written to the database - is this possible and if so how?
Very much a beginner,
Philip.
// Import Admin SDK
var admin = require("firebase-admin");
// Get a database reference to our blog
var db = admin.database();
var ref = db.ref("server/saving-data/fireblog");
First, create a database reference to your user data. Then use set() / setValue() to save a user object to the database with the user's username, full name, and birthday. You can pass set a string, number, boolean, null, array or any JSON object. Passing null will remove the data at the specified location. In this case you'll pass it an object:
var usersRef = ref.child("users");
usersRef.set({
alanisawesome: {
date_of_birth: "June 23, 1912",
full_name: "Alan Turing"
},
gracehop: {
date_of_birth: "December 9, 1906",
full_name: "Grace Hopper"
}
});
Thanks for this Yes For brevity I didn't show all the code and so I have access to the database. The problem is with sending data to it. Sometimes it works and sometimes not.
I now realise this is related to my failure to deal with Promises. I have now some understanding of these but still need to make sure that the data gets captured in the database. SO even though the Promise may return an Error I still need to re-send the data so that it will get written to the database. Still not sure whether this is advisable or even possible.
I want to load a JSONStore based on a provided param to the adapter mapped load function.
Let me explain it better.
The JSONStore initialization is like this:
collections[EMPLOYEE_COLLECTION_NAME] = {
searchFields : {ENAME: 'string', EMPNO:'integer'},
//-- Start optional adapter metadata
adapter : {
name: 'EmployeesDB',
add: 'addEmployee',
remove: 'deleteEmployee',
replace: 'updateEmployee',
load: {
procedure: 'getEmployee',
params: [region],
key: 'resultSet'
}
}
//-- End optional adapter metadata
};
//Initialize the people collection
WL.JSONStore.init(collections, options)
As you can see in the code above, even after the param region was passed to the adapter collection init, is it supposed to change during my app life cycle, so there are moments where region let's say is SOUTH, others is NORTH and so on.
I realized that even though I change this value after the store was created, the mapped load function in the adapter getEmployee (see below) always get value that region contained at the time the jsonstore was initialized regardless I change the region variable value later on. Looks like the adapter binds conf is getting at collection creation time, and never changes it
function getEmployee(data) {
WL.Logger.info('Show param:'+data);
return WL.Server.invokeSQLStatement({
preparedStatement : selectStatement,
parameters : []
});
}
Is there a way to pass parameter to the Jsonstore load function that can change after the store was initialized ?
I wanted to avoid close and init the collection again to save time and resources.
By the way, what I really need is to have flexibility on what I load from the database based on a adapter parameter that is bound to a collection.
Try something like:
WL.JSONStore.get(EMPLOYEE_COLLECTION_NAME).adapter.load.params = ['...']
Before calling WL.JSONStore.get(EMPLOYEE_COLLECTION_NAME).load().
If you want more flexibility, you can always call WL.Client.invokeProcedure and inside the onSuccess callback you can call: WL.JSONStore.get(EMPLOYEE_COLLECTION_NAME).add(['...'], {push: false}). The push: false section will make sure JSONStore understands that the data added is up-to-date with the data on the backend. This means it won't show those documents when you call: WL.JSONStore.get(EMPLOYEE_COLLECTION_NAME).getPushRequired() or WL.JSONStore.get(EMPLOYEE_COLLECTION_NAME).push().
In my responder I have:
Spanish.ADDWORD = SC.Responder.create({
didBecomeFirstResponder: function(responder) {
var store = this._store = Spanish.store.chain(); //buffer changes
var word = store.createRecord(Spanish.Word, {word: "", english: ""});
Spanish.addWordController.set("content",word);
//show the dialog
var pane = Spanish.getPath('addWordPage.mainPane');
pane.append();
pane.makeFirstResponder();
},
submit: function(){
this._store.commitChanges().destroy();
Spanish.makeFirstResponder(Spanish.READY);
}
}
Before I had the DataSource hooked-up, and I was using local, everything worked. When I click submit now no new object is created and createRecord is not being called.
A possible problem is that you are calling .destroy() immediately. This shouldn't be an issue, but as you said it was working while using fixtures (which are synchronous). Now that you are using a dataSource (which is usually asynchronous), it may be getting interrupted. Try removing the .destory(), and see if that resolves your issue.
Another option to try, is that there may be a bug in the nested store, in that if you create a new record (rather than edit an existing one), the 'did it change' test may fail (as there is nothing to compair it too), so calling commitChanges(YES) will force a commit, without the check.