ionic 2 timer causes crash in app class - ionic2

I am in an ionic 2 MyApp class, and I want to show one screen for 3 seconds then switch to another.
I get a this.nav.parent is null error.
I am trying two types of timers and neither work.
I am using tabs, and want it to go to the first tab page by the way.
gotoFirstPage()
{
//these two lines work fine
//this.nav.setRoot( TabsPage );
//this.nav.parent.select(1); //this.nav.parent is not null here
setTimeout((function()
{
this.nav.setRoot( TabsPage );
this.nav.parent.select(1); //this.nav.parent is null
}.bind(this)),3000);
let timer = Observable.timer(3000, 86400000);
timer.subscribe(t => {
this.nav.setRoot( TabsPage );
this.nav.parent.select(1); //this.nav.parent is null
});
}

I recommend to use a fat-arrow =>instead of binding this:
setTimeout(() =>
{
this.nav.setRoot( TabsPage );
this.nav.parent.select(1); //this.nav.parent is null
},3000);
If that doesn't work, then your nav object in this is null, so the problem is not the timer.

I have no idea why this.nav.parent is null but I found a better way to switch tab pages:
this.nav.setRoot( TabsPage, { tabIndex: 1 } );

Related

How to dynamically define Headers and Settings for UWP NavigationView's menu, using C++/winRT?

I'm working on a cross-platform project in C++ generating the UI dynamically, and I am struggling with C++/winRT UWP NavigationView on two problems:
When defining a NavigationViewItemHeader, the resulting header title doesn't show in the navigation menu, the space remains empty,
When trying to update the SettingsItem of the navigation menu, the value of the Settings navigation item is nullptr as returned by SettingsItem().
Here is the code I wrote for generating the menu from a list of items managed independently from the host (e.g. Windows):
bool
CANavigationView::UpdateHostView( void )
{
TNavigationItemPtr item;
TIndex index;
if( _hostViewUpdateNeeded == false )
return false;
Windows::UI::Xaml::Controls::NavigationViewItemBase hItem( nullptr );
Windows::UI::Xaml::Controls::TextBlock hText( nullptr );
winrt::hstring hTag;
// Remove all navigation items from the current host view:
_hostNavigationView.MenuItems().Clear();
_hostNavigationView.IsSettingsVisible( false );
// Build the navigation menu items:
for( index = 0; index < _navigationItems.CountOfItems(); index++ )
{
item = * _navigationItems.GetItemAtIndex( index );
if( item->identifier == kSettingsItem )
{
_hostNavigationView.IsSettingsVisible( true );
hText = Windows::UI::Xaml::Controls::TextBlock();
CSString::ConvertToUIString( item->title->GetString( gAppLanguageCode ), & hTag );
hText.Text( hTag );
// Issue #1 : cannot access to the Settings item
// _hostNavigationView.SettingsItem().as< Windows::UI::Xaml::Controls::NavigationViewItem >().Content( hText );
// SettingsItem() returns nullptr...
}
else
{
switch( item->type )
{
case eNavigationHeader:
hItem = Windows::UI::Xaml::Controls::NavigationViewItemHeader();
hText = Windows::UI::Xaml::Controls::TextBlock();
CSString::ConvertToUIString( item->title->GetString( gAppLanguageCode ), & hTag );
hText.Text( hTag );
// Issue #2: The header's title is not displayed
hItem.Content( hText );
_hostNavigationView.MenuItems().Append( hItem );
break;
case eNavigationSeparator:
hItem = Windows::UI::Xaml::Controls::NavigationViewItemSeparator();
_hostNavigationView.MenuItems().Append( hItem );
break;
case eNavigationItem:
hItem = Windows::UI::Xaml::Controls::NavigationViewItem();
CSString::ConvertToUIString( CAUIElement::GetStringFromUIIdentifier( item->identifier ), & hTag );
hItem.Tag( winrt::box_value( hTag ) );
hText = Windows::UI::Xaml::Controls::TextBlock();
CSString::ConvertToUIString( item->title->GetString( gAppLanguageCode ), & hTag );
hText.Text( hTag );
hItem.Content( hText );
hItem.as< Windows::UI::Xaml::Controls::NavigationViewItem>().Icon( GetHostIcon( item->icon ) );
_hostNavigationView.MenuItems().Append( hItem );
break;
default:
break;
}
}
}
_hostViewUpdateNeeded = false;
return true;
}
As I'm using my own string format (I'm stuck in old C++ standards...) and I18N support, I need to first convert the UTF8 string to the host (here Windows) before setting the value of the text block, using the hTag variable of type hstring. In debugging mode, the text is well transcoded in the hstring format...
What is puzzling me is the fact that both NavigationSeparator and NavigationItem cases are working fine, in line with the official Microsoft documentation (including the Tag for menu event handling and Icon setting for NavigationViewItem).
I understand this is not the "mainstream XAML way" of working on UWP user interface but so far the approach is working well on other UI elements.
Here is a screenshot of the navigation view with the empty spaces for the headers:
Also, in the example above, I logged the number of menu items in the host navigation view (_hostNavigationView.MenuItems().Size()) and got 7 as a result, which is correct...
At last, here's the detailed log I'm generating in DEBUG mode:
DBG-[000002686A230710]CANavigationView::UpdateDisplayedLanguage() {
DBG-[000002686A230710]CANavigationView::UpdateHostView() {
DBG-[000002686A230710]CANavigationView::UpdateHostView() Navigation item 0, type 2
DBG-[000002686A230710]CANavigationView::UpdateHostView() Header case: Reference Library
DBG-[000002686A230710]CANavigationView::UpdateHostView() Navigation item 1, type 1
DBG-[000002686A230710]CANavigationView::UpdateHostView() Navigation item case
DBG-[000002686A230710]CANavigationView::UpdateHostView() Navigation item 2, type 1
DBG-[000002686A230710]CANavigationView::UpdateHostView() Navigation item case
DBG-[000002686A230710]CANavigationView::UpdateHostView() Navigation item 3, type 1
DBG-[000002686A230710]CANavigationView::UpdateHostView() Navigation item case
DBG-[000002686A230710]CANavigationView::UpdateHostView() Navigation item 4, type 3
DBG-[000002686A230710]CANavigationView::UpdateHostView() Separator case
DBG-[000002686A230710]CANavigationView::UpdateHostView() Navigation item 5, type 2
DBG-[000002686A230710]CANavigationView::UpdateHostView() Header case: Project Library
DBG-[000002686A230710]CANavigationView::UpdateHostView() Navigation item 6, type 1
DBG-[000002686A230710]CANavigationView::UpdateHostView() Navigation item case
DBG-[000002686A230710]CANavigationView::UpdateHostView() Navigation item 7, type 1
DBG-[000002686A230710]CANavigationView::UpdateHostView() Settings case
DBG-[000002686A230710]CANavigationView::UpdateHostView() Value of SettingsItem(): 0000000000000000
DBG-[000002686A230710]CANavigationView::UpdateHostView() Count of menu items for the navigation view: 7 (8)
DBG-}
DBG-}
Your help in solving those two issues would be greatly appreciated !
Best regards,
Arnaud
Based on Roy's comments, it is not necessary to use TextBlock to set the value of both NavigationViewItemHeader and NavigationViewItem. Instead, it is just a case of boxing the string value into an IInspectable object:
hItem.Content( winrt::box_value( hTag ) );
Now, I have the correct display and behavior of the navigation menu:
Thank you, Roy !
UPDATE:
I also managed to change the title of the SettingsItem. According to the documentation, a good time to customize the navigation menu is when the view is loaded.
Therefore, I subscribed/registered to the Loaded() event and performed the customization from there. At that stage of the lifecycle of the navigation view, SettingsItem() returns a valid NavigationViewItem allowing me to change the title with the same string boxing approach.
Both problems are solved now!
Dynamic Headers/Footers enable different grouping options in reports, such as "By Location" or "By Location By System": Note that the words "Report Definitions" are circled above. Although reports can have up to three Dynamic Headers/Footers, some reports only have one or two Dynamic Groups.

Flutter logical decission between Video and Image in UI

I'm a little bit lost in an App I'm trying to write. I'd like to display either an image, or an Video - depending on an entry in a list.
So, if the entry in the list I'm currently displaying has a video I want to use the Chewie Player in the UI
child = Chewie(
controller: _chewieController,
)
if the entry in the list I'm currently displaying has an image I want to use CachedNetworkImage:
CachedNetworkImage(imageUrl: _questions[widget.questionno].getSourceUrl(),)
as you probably noticed, I am a programming beginner. How can I solve this problem?
Right now the code I'm trying to use in the UI looks like this:
Container(
if (_questions[widget.questionno].getVideo()=="Ja") {
child = Chewie(
controller: _chewieController,
)
} else {
child = CachedNetworkImage(imageUrl: _questions[widget.questionno].getSourceUrl(),)
}
),
Try something like this:
bool video = false
if(entryInList is Video){ //Replace Video with whatever type you would have
//for Videos
video = true
}
And in your Widget tree
child: video ? VideoWidget() : FotoWidget()
Or all in one line:
child: entryInList is Video ? VideoWidget() : FotoWidget()
finally got it working, it's probably not the best way, but whatever, it works and I'm super happy :D
child: Builder(
builder: (context) {
if (_questions[widget.questionno].getVideo()=='Ja') {
return
Container(child: Chewie(controller: _chewieController,));
} else {
return
Container(child: CachedNetworkImage(imageUrl: _questions[widget.questionno].getSourceUrl(),));
}
}
)
additionally I also had to put the whole definition of the chewie controller (which is in initState) into an if thingie.

Can I get the textarea caret position in unit test with Jasmine?

I am trying to implement '# Users Feature' with angularjs, I almost finish the feature except writing an unit test. I have a Caret module which can help me get the caret position in textarea.
I think the most important thing is to get the caret position but I dont know how to do it in jasmine.
Mydirective
.directive('atUser', function (Caret) {
return {
restrict: 'A',
link: function (scope, element) {
element.bind('focus click keydown', function () {
scope.caretPos = Caret.getPos(element);
});
scope.$watch(function () {
return scope.caretPos;
}, function (nowCaretPos) {
/* do something here */
})
}
}
})
Html
<textarea ng-model="message" at-user></textarea>
Jasmine
describe('test at user', function () {
/* some init code */
it('should get caret postion', function () {
textarea = element.find('textarea');
textarea.triggerHandler('focus');
except(textarea.scope().caretPos).toEqual(0);
/*
* then i want to simulate keydown event and type something
* and get the caret postion
* but i dont know how to do it
* /
})
})
One more thing is I dont want to use jquery.
Can anyone help me?
thanks a lot!
I just asked a similar question where I needed to set the caret position of a textarea in a Jasmine test, and I got an answer that worked (using selectionStart on programmatically-created inputs), so here is a potential solution that you can implement with Jasmine:
describe('test at user', function () {
/* some init code */
it('should get caret postion', function () {
textarea = element.find('textarea');
textarea.triggerHandler('focus');
expect(textarea.scope().caretPos).toEqual(0);
/*
* then i want to simulate keydown event and type something
* and get the caret postion
* but i dont know how to do it
*/
document.body.appendChild(textarea[0]); // I discovered this to be the key to using the .selectionStart property successfully
textarea.val('some text');
textarea[0].selectionStart = 9; // you need to move the caret manually when doing things programmatically
textarea.triggerHandler('focus');
expect(textarea.scope().caretPos).toEqual(9);
})
})

Passing parameters in Ember's Custom Events (that bubble through the View hierarchy)?

I couldn't find a way to pass arguments when using Ember's Custom Events which I found here.
I prefer avoiding solutions which target "parent" views specifically, such as this one since we lose the "bubbling".
My Usage is as following
plugins.js
Em.Object.reopen({
triggerEvent: function (eventName) {
this.$().trigger(eventName, this);
}
});
MyView.js
click: function () {
this.triggerEvent('stepClicked');
}
The code in Ember (0.96+) shows that passing an additional params is considered a manager, which isn't passed on
rootElement.delegate('.ember-view', event + '.ember', function(evt, triggeringManager) {
...
if (manager && manager !== triggeringManager) {
result = self._dispatchEvent(manager, evt, eventName, view);
} else if (view) {
result = self._bubbleEvent(view,evt,eventName);
}
Super thanks in advance,
Oren Rubin
You can pass an event object which will tell you what element is being clicked on:
click: function(event){
// will be called when when an instance's
// rendered element is clicked
console.log("element clicked: " + this.get('elementId') );
return false; // return true if you want the click event to bubble up to parent view (default it true)
}
I think an even better way would be to use {{action}} in your template. Take a look at this answer for an example.

How does MFC's "Update Command UI" system work?

I'd like to know more about how this system works, specifically when and how the framework actually decides to update a UI element.
My application has a 'tools' system where a single tool can be active at a time. I used the "ON_UPDATE_COMMAND_UI" message to 'check' the tool's icon/button in the UI, which affected both the application menu and the toolbars. Anyway, this was all working great until some point in the last couple of days, when the toolbar icons stopped getting highlighted properly.
I investigated a little and found that the update command was only being received when the icon was actually clicked. What's strange is this is only affecting the toolbars, not the menu, which is still working fine. Even when the buttons in the menu are updated the toolbar icon stays the same.
Obviously I've done something to break it - any ideas?
EDIT:
Never mind. I'd overwritten the Application's OnIdle() method and hadn't called the original base class method - that is, CWinApp::OnIdle() - which I guess is where the update gets called most of the time. This code snippet from https://msdn.microsoft.com/en-us/library/3e077sxt.aspx illustrates:
BOOL CMyApp::OnIdle(LONG lCount)
{
// CWinApp's original method is involved in the update message handling!
// Removing this call will break things
BOOL bMore = CWinApp::OnIdle(lCount);
if (lCount == 0)
{
TRACE(_T("App idle for short period of time\n"));
bMore = TRUE;
}
// ... do work
return bMore;
// return TRUE as long as there are any more idle tasks
}
Here's a good article that kinda explains how to do it. Don't use his code example with WM_KICKIDLE though, instead scroll down to the comments section. There are two code samples that explain how to do it better. I quote:
//Override WM_INITMENUPOPUP
void CDialog::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu)
{
CDialog::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);
// TODO: Add your message handler code here
if(pPopupMenu &&
!bSysMenu)
{
CCmdUI CmdUI;
CmdUI.m_nIndexMax = pPopupMenu->GetMenuItemCount();
for(UINT i = 0; i < CmdUI.m_nIndexMax; i++)
{
CmdUI.m_nIndex = i;
CmdUI.m_nID = pPopupMenu->GetMenuItemID(i);
CmdUI.m_pMenu = pPopupMenu;
// There are two options:
// Option 1. All handlers are in dialog
CmdUI.DoUpdate(this, FALSE);
// Option 2. There are handlers in dialog and controls
/*
CmdUI.DoUpdate( this, FALSE );
// If dialog handler doesn't change state route update
// request to child controls. The last DoUpdate will
// disable menu item with no handler
if( FALSE == CmdUI.m_bEnableChanged )
CmdUI.DoUpdate( m_pControl_1, FALSE );
...
if( FALSE == CmdUI.m_bEnableChanged )
CmdUI.DoUpdate( m_pControl_Last, TRUE );
*/
}
}
}
See if this helps - http://msdn.microsoft.com/en-us/library/essk9ab2(v=vs.80).aspx