Issues with Toast


#1

I plug in the toast code and try to add position to Toast using the documentation, but I get this error when I try to do ionic serve.
“getting-started/getting-started.ts(17,7): Error TS2345: Argument of type ‘{ message: string; duration: number; position: string; }’ is not assignable to parameter of type ‘ToastOptions’.
Object literal may only specify known properties, and ‘position’ does not exist in type ‘ToastOptions’.”


#2

I was able to custom code it by viewing the source code on the API reference page which has the correct toast code. Can we get an official update and fix on the current code, so a custom option is not needed?


#3

Can you please explain how you set the position? I want to set it to ‘top’ but as you said it’s not working.


#4

Let’s say for testing purposes a getting-started.ts file :
import {Component} from ‘@angular/core’;
import {NavController, Toast} from ‘ionic-angular’;
import {ScientificFactsPage} from ‘…/scientific-facts-page/scientific-facts-page’;

@Component({
templateUrl: ‘build/pages/getting-started/getting-started.html’
})
export class GettingStartedPage {

constructor(private nav:NavController) {
this.nav = nav;
}

presentToast() {
let toast = Toast.create({
message: ‘Message sent. Thank you!’,
duration: 3000
});

toast.onDismiss(() => {
console.log(‘Dismissed toast’);
});

this.nav.present(toast);
}
}

I merely reversed a few files to get it to go to the top and those files are in this folder YourApp/node_modules/ionic-angular/components/toast/

You need to alter the toast.js file and all of the .scss files.
toast.js
"use strict";
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty§) d[p] = b[p];
function () { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (
.prototype = b.prototype, new __());
};
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === “object” && typeof Reflect.decorate === “function”) r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i–) if (d = decorators[i]) r = (c < 3 ? d® : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === “object” && typeof Reflect.metadata === “function”) return Reflect.metadata(k, v);
};
var core_1 = require(’@angular/core’);
var animation_1 = require(’…/…/animations/animation’);
var transition_1 = require(’…/…/transitions/transition’);
var config_1 = require(’…/…/config/config’);
var util_1 = require(’…/…/util/util’);
var nav_params_1 = require(’…/nav/nav-params’);
var nav_controller_1 = require(’…/nav/nav-controller’);
var view_controller_1 = require(’…/nav/view-controller’);
/**

  • @name Toast
  • @description
  • A Toast is a subtle notification that appears at the bottom of the
  • screen. It can be used to provide feedback about an operation or to
  • display a system message. The toast appears on top of the app’s content,
  • and can be dismissed by the app to resume user interaction with
  • the app. It includes a backdrop, which can optionally be clicked to
  • dismiss the toast.
  • Creating

  • All of the toast options should be passed in the first argument of
  • the create method: Toast.create(opts). The message to display should be
  • passed in the message property. The showCloseButton option can be set to
  • true in order to display a close button on the toast. See the create
  • method below for all available options.
  • Dismissing

  • The toast can be dismissed automatically after a specific amount of time
  • by passing the number of milliseconds to display it in the duration of
  • the toast options. It can also be dismissed by clicking on the backdrop,
  • unless enableBackdropDismiss is set to false upon creation. If showCloseButton
  • is set to true, then the close button will dismiss the toast. To dismiss
  • the toast after creation, call the dismiss() method on the Toast instance.
  • The onDismiss function can be called to perform an action after the toast
  • is dismissed.
  • @usage
  • constructor(nav: NavController) {
  • this.nav = nav;
  • }
  • presentToast() {
  • let toast = Toast.create({
  • message: 'User was added successfully',
    
  • duration: 3000
    
  • });
  • toast.onDismiss(() => {
  • console.log('Dismissed toast');
    
  • });
  • this.nav.present(toast);
  • }
  • @demo /docs/v2/demos/toast/
    /
    var Toast = (function (_super) {
    __extends(Toast, _super);
    function Toast(opts) {
    if (opts === void 0) { opts = {}; }
    opts.dismissOnPageChange = util_1.isPresent(opts.dismissOnPageChange) ? !!opts.dismissOnPageChange : false;
    _super.call(this, ToastCmp, opts);
    this.viewType = ‘toast’;
    this.isOverlay = true;
    this.usePortal = true;
    // by default, toasts should not fire lifecycle events of other views
    // for example, when an toast enters, the current active view should
    // not fire its lifecycle events because it’s not conceptually leaving
    this.fireOtherLifecycles = false;
    }
    /
    *
    • @private
      /
      Toast.prototype.getTransitionName = function (direction) {
      var key = ‘toast’ + (direction === ‘back’ ? ‘Leave’ : ‘Enter’);
      return this._nav && this._nav.config.get(key);
      };
      /
      *
    • @param {string} message Toast message content
      /
      Toast.prototype.setMessage = function (message) {
      this.data.message = message;
      };
      /
      *
    • Toast options
    • | Property | Type | Default | Description |
    • |-----------------------|-----------|-----------------|---------------------------------------------------------------------------------------------------------------|
    • | message | string | - | The message for the toast. Long strings will wrap and the toast container will expand. |
    • | duration | number | - | How many milliseconds to wait before hiding the toast. By default, it will show until dismiss() is called. |
    • | cssClass | string | - | Any additional class for custom styles. |
    • | showCloseButton | boolean | false | Whether or not to show a button to close the toast. |
    • | closeButtonText | string | “Close” | Text to display in the close button. |
    • | dismissOnPageChange | boolean | false | Whether to dismiss the toast when navigating to a new page. |
    • @param {object} opts Toast options. See the above table for available options.
      /
      Toast.create = function (opts) {
      if (opts === void 0) { opts = {}; }
      return new Toast(opts);
      };
      return Toast;
      }(view_controller_1.ViewController));
      exports.Toast = Toast;
      /
      *
  • @private
    */
    var ToastCmp = (function () {
    function ToastCmp(_nav, _viewCtrl, _config, _elementRef, params, renderer) {
    this._nav = _nav;
    this._viewCtrl = _viewCtrl;
    this._config = _config;
    this._elementRef = _elementRef;
    this.dismissTimeout = undefined;
    this.d = params.data;
    this.created = Date.now();
    if (this.d.cssClass) {
    renderer.setElementClass(_elementRef.nativeElement, this.d.cssClass, true);
    }
    this.id = (++toastIds);
    if (this.d.message) {
    this.hdrId = ‘toast-hdr-’ + this.id;
    }
    }
    ToastCmp.prototype.ionViewDidEnter = function () {
    var _this = this;
    var activeElement = document.activeElement;
    if (activeElement) {
    activeElement.blur();
    }
    var focusableEle = this._elementRef.nativeElement.querySelector(‘button’);
    if (focusableEle) {
    focusableEle.focus();
    }
    // if there’s a duration set, automatically dismiss.
    if (this.d.duration) {
    this.dismissTimeout =
    setTimeout(function () {
    _this.dismiss(‘backdrop’);
    }, this.d.duration);
    }
    };
    ToastCmp.prototype.cbClick = function () {
    if (this.isEnabled()) {
    this.dismiss(‘close’);
    }
    };
    ToastCmp.prototype.dismiss = function (role) {
    clearTimeout(this.dismissTimeout);
    this.dismissTimeout = undefined;
    return this._viewCtrl.dismiss(null, role);
    };
    ToastCmp.prototype.isEnabled = function () {
    var tm = this._config.getNumber(‘overlayCreatedDiff’, 750);
    return (this.created + tm < Date.now());
    };
    ToastCmp = __decorate([
    core_1.Component({
    selector: ‘ion-toast’,
    template: “\n <div class=“toast-wrapper”>\n <div class=“toast-container”>\n <div class=“toast-message” id=”{{hdrId}}" *ngIf=“d.message”>{{d.message}}\n <button clear class=“toast-button” *ngIf=“d.showCloseButton” (click)=“cbClick()”>\n {{ d.closeButtonText || ‘Close’ }}\n \n \n \n ",
    host: {
    ‘role’: ‘dialog’,
    ’[attr.aria-labelledby]’: ‘hdrId’,
    ’[attr.aria-describedby]’: ‘descId’,
    },
    }),
    __metadata(‘design:paramtypes’, [nav_controller_1.NavController, view_controller_1.ViewController, config_1.Config, core_1.ElementRef, nav_params_1.NavParams, core_1.Renderer])
    ], ToastCmp);
    return ToastCmp;
    }());
    var ToastSlideIn = (function (_super) {
    __extends(ToastSlideIn, _super);
    function ToastSlideIn(enteringView, leavingView, opts) {
    _super.call(this, opts);
    var ele = enteringView.pageRef().nativeElement;
    var wrapper = new animation_1.Animation(ele.querySelector(’.toast-wrapper’));
    wrapper.fromTo(‘translateY’, ‘-100%’, 20 + “px”);
    this.easing(‘cubic-bezier(.36,.66,.04,1)’).duration(400).add(wrapper);
    }
    return ToastSlideIn;
    }(transition_1.Transition));
    var ToastSlideOut = (function (_super) {
    __extends(ToastSlideOut, _super);
    function ToastSlideOut(enteringView, leavingView, opts) {
    _super.call(this, opts);
    var ele = leavingView.pageRef().nativeElement;
    var wrapper = new animation_1.Animation(ele.querySelector(’.toast-wrapper’));
    wrapper.fromTo(‘translateY’, 20 + “px”, ‘-100%’);
    this.easing(‘cubic-bezier(.36,.66,.04,1)’).duration(300).add(wrapper);
    }
    return ToastSlideOut;
    }(transition_1.Transition));
    var ToastMdSlideIn = (function (_super) {
    __extends(ToastMdSlideIn, _super);
    function ToastMdSlideIn(enteringView, leavingView, opts) {
    _super.call(this, opts);
    var ele = enteringView.pageRef().nativeElement;
    var backdrop = new animation_1.Animation(ele.querySelector(‘ion-backdrop’));
    var wrapper = new animation_1.Animation(ele.querySelector(’.toast-wrapper’));
    backdrop.fromTo(‘opacity’, 0, 0);
    wrapper.fromTo(‘translateY’, ‘-100%’, “0px”);
    this.easing(‘cubic-bezier(.36,.66,.04,1)’).duration(400).add(backdrop).add(wrapper);
    }
    return ToastMdSlideIn;
    }(transition_1.Transition));
    var ToastMdSlideOut = (function (_super) {
    __extends(ToastMdSlideOut, _super);
    function ToastMdSlideOut(enteringView, leavingView, opts) {
    _super.call(this, opts);
    var ele = leavingView.pageRef().nativeElement;
    var wrapper = new animation_1.Animation(ele.querySelector(’.toast-wrapper’));
    var backdrop = new animation_1.Animation(ele.querySelector(‘ion-backdrop’));
    wrapper.fromTo(‘translateY’, 0 + “px”, ‘-100%’);
    backdrop.fromTo(‘opacity’, 0, 0);
    this.easing(‘cubic-bezier(.36,.66,.04,1)’).duration(450).add(backdrop).add(wrapper);
    }
    return ToastMdSlideOut;
    }(transition_1.Transition));
    var ToastWpPopIn = (function (_super) {
    __extends(ToastWpPopIn, _super);
    function ToastWpPopIn(enteringView, leavingView, opts) {
    _super.call(this, opts);
    var ele = enteringView.pageRef().nativeElement;
    var backdrop = new animation_1.Animation(ele.querySelector(‘ion-backdrop’));
    var wrapper = new animation_1.Animation(ele.querySelector(’.toast-wrapper’));
    wrapper.fromTo(‘opacity’, ‘0.01’, ‘1’);
    wrapper.fromTo(‘scale’, ‘1.3’, ‘1’);
    backdrop.fromTo(‘opacity’, 0, 0);
    this.easing(‘cubic-bezier(0,0 0.05,1)’).duration(200).add(backdrop).add(wrapper);
    }
    return ToastWpPopIn;
    }(transition_1.Transition));
    var ToastWpPopOut = (function (_super) {
    __extends(ToastWpPopOut, _super);
    function ToastWpPopOut(enteringView, leavingView, opts) {
    _super.call(this, opts);
    var ele = leavingView.pageRef().nativeElement;
    var backdrop = new animation_1.Animation(ele.querySelector(‘ion-backdrop’));
    var wrapper = new animation_1.Animation(ele.querySelector(’.toast-wrapper’));
    wrapper.fromTo(‘opacity’, ‘1’, ‘0.00’);
    wrapper.fromTo(‘scale’, ‘1’, ‘1.3’);
    backdrop.fromTo(‘opacity’, 0, 0);
    this.easing(‘ease-out’).duration(150).add(backdrop).add(wrapper);
    }
    return ToastWpPopOut;
    }(transition_1.Transition));
    transition_1.Transition.register(‘toast-slide-in’, ToastSlideIn);
    transition_1.Transition.register(‘toast-slide-out’, ToastSlideOut);
    transition_1.Transition.register(‘toast-md-slide-in’, ToastMdSlideIn);
    transition_1.Transition.register(‘toast-md-slide-out’, ToastMdSlideOut);
    transition_1.Transition.register(‘toast-wp-slide-out’, ToastWpPopOut);
    transition_1.Transition.register(‘toast-wp-slide-in’, ToastWpPopIn);
    var toastIds = -1;

toast.ios.scss
.toast-wrapper {
position: absolute;
top: 0;
right: 10px;
left: 10px;
z-index: $z-index-overlay-wrapper;
display: block;

margin: auto;

max-width: 300px;

border-radius: $toast-ios-border-radius;

background: rgba(0, 0, 0, 0.9);

transform: translate3d(0, -100%, 0);
}

toast.md.scss
.toast-wrapper {
position: absolute;
top: 0;
right: 0;
left: 0;
z-index: $z-index-overlay-wrapper;
display: block;

margin: auto;

width: $toast-width;
max-width: $toast-max-width;

background: rgba(0, 0, 0, 0.9);

transform: translate3d(0, -100%, 0);
}

toast.scss
.toast-wrapper {
position: absolute;
top: 0;
right: 0;
left: 0;
z-index: $z-index-overlay-wrapper;
display: block;

margin: auto;

max-width: $toast-max-width;

transform: translate3d(0, -100%, 0);
}

toast.wp.scss
.toast-wrapper {
position: absolute;
top: 0;
left: 0;
z-index: $z-index-overlay-wrapper;
display: block;

margin: auto;

max-width: $toast-max-width;

border-radius: $toast-wp-border-radius;
background: rgba(0, 0, 0, 0.9);

transform: translate3d(0, -100%, 0);
}


#5

Ouuuf thanks for that @cambronjay! But I really wouldn’t like to mess up anything by editing so many things just for something so simple… :confused:

Perhaps someone from Ionic can share an easier way to do this, since in theory it’s supported?
Thanks though! :slight_smile:

Edit:
To make it clear, I want the behavior that is shown here: http://ionicframework.com/docs/v2/api/components/toast/Toast/
when clicking the Show Toast Top.

The code suggested on the left does not work for position setting.


#6

If you want the position ability you have to modify the toast.ts file and the rest of the files within the toast component to match the API reference page source code. They have the correct code on the reference page, but not within the demo or setup code. I pulled my code from the viewing the api reference page source code. I only needed the top toast, so I modified it to only support top.