calling a dojo JsonRest with parameters - json

When calling JsonRest using dojo, how can I pass parameters with it.
var rest = new JsonRest({
target: "/path/to/service"
});

JsonRest example:
require(["dojo/store/JsonRest"], function(JsonRest){
// create a store with target your service
var store = new JsonRest({
target: "/path/to/service"
});
// make a get request passing some options
store.query("foo=bar", {
start: 5,
count: 5,
sort: [
{ attribute: "color", descending: true }
]
}).then(function(results){
// result here
});
});
The function to use in your case is query with signature query(query, options)
When called, query will trigger a GET request to {target}?{query}, as described in dojo docs.
Please keep in mind that:
If query is an object, it will be serialized.
If query is a string, it is appended to the URL as-is.
If options includes a sort property, it will be serialized as a query parameter as well;
Your service/API should:
Return a array of objects in JSON format.
Return an empty array if no match is found.

Related

getting nested objects in mongoose

I'm trying to retrieve an array of objects in mongoose using code that looks like this.
mongoPlaces
.find({
'person.types': {$in: ["student"]}
})
.select('family')
.lean()
.limit(3)
.exec(function (err, families) {
console.log()
})
the results is something like this
[
0: family:{objects}
1: family:{objects}
2: family:{objects}
]
and I need something like this
[
0: {objects}
1: {objects}
2: {objects}
]
is there some way to retrieve the contents of an object instead of the object itself using mongoose without having to make a loop and correct the array or is there any other way to make this cleanly?
There's no way to do this with mongoose, but there are ways of making it cleanly:
mongoPlaces
.find({
'person.types': {$in: ["student"]}
})
.select('family')
.lean()
.limit(3)
.exec(function (err, docs) {
var families = docs.map(function pluckFamily(doc) {
return doc.family;
});
return families;
});
In this example, map feeds each retrieved document to the function pluckFamily, and forms another array with all the values that that function returned.
If you're going to do a lot of this, you may want to check out the underscore library. It includes a pluck function.

Backbone model .toJSON() doesn't work after .fetch()

Good day! I need to render a model's attributes to JSON so I can pass them into a template.
Model:
var UserInfo = Backbone.Model.extend({
url: appConfig.baseURL + "users/",
});
Template:
<script type="text/html" class="template" id="profile-form">
<h2 class="ui-li-heading"><%= username %></h2>
<p class="ui-li-desc"><strong><%= phone %></strong></p>
</script>
View:
var ProfilePageView = Backbone.View.extend({
events: {
'click #edit': "edit"
},
initialize: function () {
this.template = $.tpl['profile-form'];
var user = new UserInfo()
user.fetch({
data: $.param({email: localStorage.getItem('user_email')}),
type: 'POST'
});
console.log(user) //returns correct object with attrs
console.log(user.toJSON()) //returns empty object
},
render: function (eventName) {
$(this.el).html(this.template());
},
edit: function () {
window.workspace.navigate('#account/edit', { trigger: true});
}
});
When i put in console something like this, user.toJSON() returns correct data
var user = new UserInfo();
user.fetch({
data: $.param({email: localStorage.getItem('user_email')}),
type: 'POST'
});
But when i put it to my view, its returns Object {}.
Where is a mistake or tell me how can differently pass to the template data received from the server in json format? Thanks!
You appear to have two problems. fetch is asyncronous, so you need to use a callback to use the information. But first, an explanation about toJSON. .toJSON() doesn't actually return a JSON string, it returns an object that is what you want JSON to stringify. This allows you to modify the toJSON method to customize what attributes will be taken from your model or collection and added to the JSON string representation of your model. Here is a quotation from the Backbone.js docs:
toJSON collection.toJSON([options])
Return a shallow copy of the model's attributes for JSON
stringification. This can be used for persistence, serialization, or
for augmentation before being sent to the server. The name of this
method is a bit confusing, as it doesn't actually return a JSON string
— but I'm afraid that it's the way that the JavaScript API for
JSON.stringify works.
So you should replace this line in your code
console.log(user.toJSON())
with this one
console.log(JSON.stringify(user))
The object that you saw was returned by toJSON will then be turned into JSON.
Now, even after you do that, it won't work properly, because you will execute the console.log before you get the data for your model from fetch. fetch is asynchronous, so you need to call any code you want to be executed after the fetch is done in the success callback:
user.fetch({
data: $.param({email: localStorage.getItem('user_email')}),
type: 'POST',
success: function(){
console.log(user);
console.log(JSON.stringify(user));
}
});

SAP UI5 - How to pass values for a controller?

I want to pass values from a view to controller on button press.In view am passing productJson which is an object.But i am unable to retrieve that value in controller.Please help.
View js:
new sap.m.Button({
text: "Add to Cart",
press:[oController.addtoCartBtnPress,oController,productJson],
})
Controller js:
addtoCartBtnPress:function(e,oView,productJson)
{
}
Result:
oView and productJson values are returned as undefined.
The data should be first value in the press array. Per the sdk docs for sap.m.Button:
press : fnListenerFunction or [fnListenerFunction, oListenerObject] or
[oData, fnListenerFunction, oListenerObject]
The listener function should then have 2 arguments: 1-the event; and 2- the data.
onPressFn: function(evt, data) { ... }
To get the view, just use:
var view = this.getView();
"this" will be equal to whatever you pass as the third value in the press array, and should usually be the controller in order to match the behaviour of xml/html views.
And an alternative to passing the data in the press call would be to use the view-model binding, especially if you are already using that model binding elsewhere in the view. But it depends how many products you have and other factors so I won't assume it will be ideal for your case.
//in the view
var productModel = new sap.ui.model.json.JSONModel(productJson);
view.setModel(productModel, "product");
//in the controller:
var data = view.getModel("product").getData();

Populate Dojo's datagrid with JsonRest and custom json arrays

I have a grid that I am creating drawing off a JSON data source that is formatted like this:
[{"user":{"username":"foo","url":"bar"}},
[{"product":{"name":"banana","price":"85"}},
{"product":{"name":"peach","price":"66"}},
{"product":{"name":"strawberry","price":"78"}}
]
]
But I cannot figure out how to tell datagrid to use the contents of the products to populate the datagrid. Here is my datagrid code:
<script>
require(["dojo/store/JsonRest"], function (JsonRest) {
myStore = new JsonRest({ target: 'myurl', handleAs: 'json'
});
});
require(["dojox/grid/DataGrid", "dojo/data/ObjectStore", "dojo/domReady!"
], function (DataGrid, ObjectStore) {
grid = new DataGrid({
store: dataStore = new ObjectStore({ objectStore: myStore }),
structure: [
{ name: "Procuct", field: "name", width: "200px" }
]
}, "grid3");
grid.startup();
});
</script>
<div id="grid3"></div>
I do not get any error, but I cannot see that the grid gets populated.
It is a similar question to THIS, but the data structure is a bit different.
I think it has something to do with your json structure.
The first part of your jsonArray is an object, the second an array:
[object,ArrayOfProducts]
How should DataGrid find the necessary data if you hide it in an array within an array & then inside the attribute product.
Try passing something simple via json like:
[{"name":"banana","price":"85"},
{"name":"peach","price":"66"},
{"name":"strawberry","price":"78"}]
Have you tried grid.renderArray(dataStore) to populate the grid with the conent ?
An option is to append a new property to the json object prior to dataStore.query() call. This can be accomplished with dojo/aspect. See article for other examples.
aspect.before(dataStore, "query", function(items) {
items.forEach(function(item) {
//Do something here. I'll combine two properties.
item.newProperty = item.propertyValueA + "-" item.propertyValueB;
return item;
});
return items;
});
When dataStore.query() is called, the function above is called above. This results in a new property be added to the json object. In the example above, the newProperty is a concatenation of propertyValueA and propertyValueB.
This may allow you to manipulate the json as needed.

Reloading a json store with new parameters ExtJs Ext.data.JsonStore

I am currently having trouble of reloading a json store with new parameters. Here is my store:
newsletters = new Ext.data.JsonStore({
url: '/newsletters/',
root: 'results',
fields: [
'id',
'body'
'recipients'
],
baseParams: { command: 'json', to: dateTo, from: dateFrom },
autoLoad: true
});
dateTo and dateFrom are initally empty strings ( '' ) and checking in firebug /newsletters is called with the correct parameters.
Now none of the following techniquest work:
Changing the values of dateTo and dateFrom then calling newsletters.reload() still calls the page with the parameters to and from being empty strings.
Calling newsletters.reload( { to: 'test1', from: 'test2' } ); still sees the parameters as empty strings.
Finally as from the manual I have tried:
lastOptions = newsletters.lastOptions;
Ext.apply(lastOptions.params, {
to: 'test1',
from: 'test2'
});
newsletters.reload(lastOptions);
This again does not request /newsletters with the updated parameters.
Any advice appreciated!
You can actually pass params object to the load() method
newsletters.load({
params: {to: 'test1', from: 'test2'}
})
From the docs, you can probably do :
store.setBaseParam('to', dateTo);
Now, if I understand correctly, you want your baseParams to be changed whenever dateTo and dateFrom are changed.
You could try :
var dateTo = '', dateFrom = '';
store.on('beforeload', function(s) {
s.setBaseParam('to', dateTo);
s.setBaseParam('from', dateFrom);
});
// This should work :
dateTo = 1;
dateFrom = 2;
store.load();
My problem was: I have a store that shall request data over a proxy to back-end. This request shall hold a parameter named filter, which will just help back-end to decide which is the set of result the client is interested in. This parameter is loaded from a Combobox or some other component which the user can use to express which filter shall be used.
From my point of view the parameters shouldn't be set to the Store and neither using the load parameter. I will explain why:
Configuring parameters to the store would imply that every other component using the same store will have this parameters configured, meaning you can have concurrence problems.
And on the second case, it is not interesting to have it configurable over load method, because you don't wanna every single time explicit make use of the load method by your self, remember that there are already some components like paging and custom components that triggers this method.
What would be the right way from my point of view:
Every time that a load is triggered, we just attach the additional parameter in a non-intrusive way. Meaning that the trigger will not need to have any change (remember here trigger could be any component that executes store.load()) and the store shall be not aware about this new parameter.
You can see here clearly that this shall be an operation done before request data to proxy, and in my case I implemented as a listener for the beforeload event. When beforeload is executed, I just aggregate the new parameters to the operation parameter of the listener that according documentation is: beforeload( store, operation, eOpts ). The final implementation is something like:
store.on({
beforeload: function (store, operation, opts) {
Ext.apply(operation, {
params: {
filterName: Ext.getCmp('filterCombo').getValue()
}
});
}
});