icCube reporting custom widget rendering when no data - iccube

I created a new widget in icCube, working as desired when there is data...
But when the underlying MDX returns no data, I need to tell it to the user or to show something else...
How can I catch the fact that the MDX is in error or that it does not return any value?

Related

How do I query a sub collection in EmberFire?

I am currently trying to fetch data from FireStore using EmberFire. Right now, my collection is /users and in there I store a user ID. Under the user ID I create another subcollecion, containing an array called /presets.
I want to use EmberFire to retrieve the presets for the currently logged in user. How can I tell this to EmberFire?
I tried fetching other data using EmberFire and it worked fine. For example, fetching documents from a collection works perfectly fine, I just have never used sub collections. Hence the question.
What I would like to achieve is something like
this.store.query('/users/pLvAT0TSbAjsnXoVmMF7yEG3mkW2/presets')
to get to the data stored in (collection users) -> (document pLvAT0TSbAjsnXoVmMF7yEG3mkW2) -> (collection presets).
Of course I would like to then use the traditional workflow to turn the documents in presets into views.
Right now, I am only able to work with a single collection. Nested collections are not something I am able to work with.
Does anyone have an idea on how to solve this?
A general answer would be:
this.store.find('users', 'pLvAT0TSbAjsnXoVmMF7yEG3mkW2').then((user)=>{
return user.get('presets');
})
But it assumes some things done "the Ember way":
There's User model
There's a Preset model
There's a hasMany relationship between User and Preset like this:
// app/models/user.js
import DS from 'ember-data';
const { Model, attr, hasMany } = DS;
export default Model.extend({
presets: hasMany('preset', { subcollection: true })
});
Although the current version of Emberfire (v3-rc2) doesn't work pretty well with Subcollections, you'll be able to fetch records, but not create or update one.
Sources:
Emberfire guides (right now kind of empty, but hopefully someday it'll have good info)

2sxc List.Presentation in General View

I have an entity type "Post" and I would like to create a view that will show one random Post with a given category. I created a Data pipeline that grabs all posts and I created a view with ListPresentation = a "TemplateSettings" entity type that lets me choose categories.
I planned to use the Razor template to filter the items for those matching the categories in List.Presentation.Categories. But, I can't seem to reference List.Presentation.Categories. I get an error that System.Collections.Generic.List doesn't contain an entry for "Presentation". When I use #ListPresentation, the whole object in null... so #ListPresentation.Toolbar, etc. all throw errors, despite me having set a "Demo Item".
Can anybody see what would be wrong with this setup? How do I reference List Presentation stuff in Razor?
Thanks.
I figured this out... The direct thing seems to be "ListPresentation", but the snippets use "List.Presentation". Still, it wasn't working in my case because I was using a data query that didn't include the module data. So, I had to modify that query to include the module data as well as the full list of entities, regardless of the module. Then, I got the full list from one data stream, and the ListPresentation fields were available.
Note also that you can use ListContent.Presentation - that would be the newest, most consistent API which always places Presentation information as a property of the entity it's describing.

How to get an item in a collection with extra attributes

I currently get an item in a collection for a user like so:
me.user = Backbone.Collection.Users.collection().get(id);
This returns the default set of attribute required in the app. On the user profile page, I want to show additional attributes that aren't necessary anywhere else.
How can I get an item in a collection (which queries the server) with additional attributes that I can specify?
Thanks
So to go along with the comment, what I think you want is to produce extra models instead of creating two user models, one with redundant + extra data.
One way you could do this is to give a relationship between different models.
Say a user model consists of simply a name and email. That's fine and dandy but you also want to render a user profile on the page (or whatever 'extras' you intend.) This seems like a good opportunity to create a separate model representing the extra data you desire.
You can do it a few ways. For example, if every user has a profile you could bake it into your user model. Something like when you create a user model:
user.profile = new Profile(); // model
I've seen some people put other models inside a model's attributes user.set('profile', new Profile()) but I'm not sure if this is a great idea. I like to keep my model attributes isolated to just that model.
Each profile model would have a url that corresponds to the model.id.
So then you could just user.profile.fetch() and use that profile attributes to populate the data in your view. Maybe it does something like /user/1/profile
Another aspect about your question that I think you might be alluding to is sending data from the server in one go when you fetch the collection. Maybe your server replies with data like this:
[{"name":"Jake", "email":"j#stack.com", "profile":"{"aboutme":"Some story"}"}, ... ]
and the profile data is only available for those who have it etc. In this case, you can then use the parse() function to pull out that extra data out and doing something before sending the name and email attributes through to the model set method.
Although, recently I think I read that using the parse to do stuff with the extra data is bad form. Override set So instead of parsing, you might just want to save that for namespacing and then in your overridden set method do something like:
set: function(attributes, options) {
if (!_.isUndefined(this.profile) && attributes.profile) {
this.profile = new Profile();
this.profile.set(attributes.profile);
} else if (attributes.profile) {
this.profile.set(attributes.profile);
}
delete attributes.profile;
return Backbone.Model.prototype.set.call(this, attributes, options);
}
You can do something similar for really unique users such as the main user using your app. When I instantiate a user model for my app (the one representing user him/herself) I also initialize a few other special models only that user would have (like an auth model for fetching authentication data etc.)
I'm not sure if I hit what you were asking but I hope I hit something.
Is collection an instance already, and I assume so? If so, you should only do:
me.user = Backbone.Collection.Users.collection.get(id);
I.e. removing the brackets () after collection.

How do I get an ID after saving an ExtBase Model?

After creating a model and adding it to a repository I want to have the new ID for different purposes (creating a mail, updating other fields outside the Extbase world)
$page = t3lib_div::makeInstance('Tx_MyExt_Domain_Model_Page');
$page->setTitle('Hello World');
$this->pageRepository->add($page);
At this point $page hasn't got an ID yet, uid is null.
$page->getUid(); // returns null
When does it get it? And how can I retrieve in on runtime?
In ExtBase, objects are "managed". This means every persistence transaction (add/remove/update) is simply noted in the underlying logic, but not yet executed until the appropriate time (like the end of processing a request). So, just because you add an object to a repository doesn't mean that it's actually added yet. That actually happens once $persistenceManager->persistAll() is called, which isn't something you need to do manually, ever. The point is, your $page object won't have a UID until it's saved and that's why $page->getUid() returns null. Look here for a great explanation.
I suspect that you are trying to do something outside of the ExtBase object/MVC lifecycle. At least, last time I got null when I tried to get the UID of an object, it was because I wasn't operating within the framework appropriately.
However, if you post some more code and give us a bigger picture of what you're trying to achieve, maybe we can help you get to a point where that object actually has a UID. For instance, if you're in a Controller object, tell us which Action method you're in, or if you're in a Repository object, tell us what you're trying to get from the repository and where/how you plan on using the query results.
EDIT
Just guessing here, but I'm assuming you're executing this code in some action of a controller. Since after the controller is executed a view is rendered, you can just pass the page object to the view:
$this->view->assign('page', $page);
And then in your view you can use the page object in a link:
<f:link.action action="show" arguments="{page:page}">
See this page object
</f:link.action>
And then in the show action of your controller you can show the page:
public function showAction(Tx_MyExt_Domain_Model_Page $page) {
// Do whatever you need to show the page in the `Show.html` template
}
I really am just guessing here. If you can give us a larger picture of what you're trying to do, what your action methods are supposed to do and things like that, we can answer your question a little more confidently.
(I'm also assuming that your page object isn't a replacement for the regular TYPO3 pages and that they are something totally different. It's much easier to deal with those TYPO3 pages through the backend interface than at the php level.)
You can call persistence manager explicitly in Your controller like this
#TYPO3 4.x
$persistenceManager = $this->objectManager->create('Tx_Extbase_Persistence_Manager');
$persistenceManager->persistAll();
#TYPO3 6.x
$persistenceManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager');
$persistenceManager->persistAll();

Writing changes from editable datagrid back to local data store - Adobe Air/Flex

I am using Adobe Air to get data from SalesForce, and present it in a datagrid.
I am using a query to get the data, and then put it into an arraycollection that is bound to the datagrid, this works correctly and the data is displayed.
I have made the datagrid editable, and I am able to change the values in the datagrid, but I cannot find how to save the changes to the local database.
I am using the following code:-
protected function VisitReportGrid_changeHandler(event:ListEvent):void{
app.wrapper.save(VisitReportGridProvider)
}
But this has the following error when I try and compile it:-
1067: Implicit coercion of a value of type mx.collections:ArrayCollection to an unrelated type mx.data:IManaged.
Obviously I am doing this wrong, but I cannot find the correct syntax.
Thanks in advance for your help
Roy
This code is not enough to understand where actually is the problem
Need to know what is VisitReportGridProvider, what is wrapper.save() method.
**after comment:
F3DesktopWrapper.save():
public function save(item:IManaged):void
Saves the specified Managed object to the local database. You must make an explicit call to syncWithServer() to update the data on the salesforce server. However, do not call syncWithServer() too often (batch your save calls) as this may use up your alloted API usage. If the item is in conflict, the conflict will be resolved.
Parameters:
item:IManaged — The managed object to create or update.
you're passing parameter with type ArrayCollection which doesn't implement IManaged interface.
You need to pass the item in the ArrayCollection that was changed to the save function. Like:
acc.fieldCollection.updateObject(new AsyncResponder(function(o:Object, t:Object):void {
app.wrapper.save(o as Account);
}, function(e:Object):void {
}));

Resources