Where does the data from Modal get saved and how to target the variables?


#1

I am creating a simple app to create work tickets. The basic principle is lists. I’ve created the list view with a modal screen with a two question test form. The modal works like it should and displays the inputed values onto the lists page that used ng-repeat. When you click on the ticket it takes you to the ticket detail page, but I tried to insert ticket detail such as {{ ticket.title }}, but the page is blank. I know I am missing something but since I am fairly new to this, I don’t seem to be smart enough to figure out the answer. I may need a controller specific to the detail page to show items specific to a particular ticket, but again, I can’t figure it out. Thank you for your help.

Here is my list view code

<ion-nav-view class="bar bar-positive">
<button class="button button-icon icon ion-ios7-minus-outline"
ng-click="data.showDelete = !data.showDelete"></button>
<button class="button" ng-click="newTicket()">New Ticket</button>
<ion-list show-delete="data.showDelete">

  <ion-item ticket="ticket" ng-repeat="ticket in tickets" type="item-text-wrap" href="#/app/ticket/{{ticket.id}}">
    <h3>{{ticket.title}}</h3>
    <p>{{ticket.description}}</p>
      <ion-delete-button class="ion-minus-circled"
             ng-click="tickets.splice($index, 1)">
      </ion-delete-button>
  </ion-item>
  
</ion-list>

And, here is the ticket detail page, where only the hard coded button appears

<ion-view class="title">
  <ion-content padding="true">
    <p>{{ ticket.title }} <br> {{ ticket.description }}</p>
    <p><a class="button button-small icon ion-arrow-left-b" href="#/app/tickets"> All Tickets</a></p>
  </ion-content>
</ion-view>

And, last but not least, my controller

    .controller('TicketIndexCtrl', function ($scope, $ionicModal) {

  $scope.tickets = [];

  // Create and load the Modal
  $ionicModal.fromTemplateUrl('new-ticket.html', function(modal) {
    $scope.ticketModal = modal;
  }, {
    scope: $scope,
    animation: 'slide-in-up'
  });

  // Called when the form is submitted
  $scope.createTicket = function(ticket) {
    $scope.tickets.push({
      title: ticket.title,
      description: ticket.description
    });
    $scope.ticketModal.hide();
    ticket.title = "";
  };

  // Open our new task modal
  $scope.newTicket = function() {
    $scope.ticketModal.show();
  };

  // Close the new task modal
  $scope.closeNewTicket = function() {
    $scope.ticketModal.hide();
  };

    })

#2

If i’ve understood well, when you list your tickets with ng-repeat, the data is showed correctly, but if you try to get the info of a concrete ticket in the detail page, it does not work.

It may be because in your controller TicketIndexCtrl, the object $scope.tickets have multiple tickets stored in it.

if you want to use the same controller to access to a specific ticket, you can do that by writing: {{tickets[0].title}} (this will provide the title of your first ticket).

If you want to use a diferent controller (I recommend you that) and use a parameter as your ticket id, you can use a foreach ( https://docs.angularjs.org/api/ng/function/angular.forEach ) to access the desired object, store it on a new $scope var like for example $scope.ticket and then you can freely access to {{ticket.title}}

Tip: Take a look at the $index var in ng-repeat, it may heko you access easily to a desired object of a collection. ( https://docs.angularjs.org/api/ng/directive/ngRepeat )


#3

@bonda thank you for the explanation; it helped greatly. I actually was doing some tests before noticing your reply and found that if creating a new ticket and not using the next sequential ticket.id, then the info would show correctly. Once I manually entered the id in the modal window, which is not ideal, then things worked. Thank you again. I will try and code it so the ‘id’ is added automatically when creating a new ticket.

Awesome!!!


#4

@bonda Ok, my brain hurts and I need an Advil :slight_smile:

Below is the contents of my controller as well as a snippet from it so you don’t need to look for what I am asking. Instead of manually entering the next sequential ticket.id into the modal window, is there a way to have it automatically assign the next ‘id’ available? Thank you for you help…!!

Snippet I think the code should go if I were to guess

  // Called when the form is submitted
  $scope.createTicket = function(ticket) {
    $scope.tickets.push({
      name: ticket.name,
      id: ticket.id //This should be automated not manual...
    });
    $scope.ticketModal.hide();
    ticket.name = "";
  };

Here is my entire controller contents just in case you need it.

angular.module('starter.controllers', [])

.controller('DashCtrl', function($scope) {
})

.controller('TicketsCtrl', function($scope, Tickets, $ionicModal) {
  $scope.tickets = Tickets.all();

   // No need for testing data anymore
  //$scope.tickets = [];

  // Create and load the Modal
  $ionicModal.fromTemplateUrl('new-ticket.html', function(modal) {
    $scope.ticketModal = modal;
  }, {
    scope: $scope,
    animation: 'slide-in-up'
  });

  // Called when the form is submitted
  $scope.createTicket = function(ticket) {
    $scope.tickets.push({
      name: ticket.name,
      id: ticket.id
    });
    $scope.ticketModal.hide();
    ticket.name = "";
  };

  // Open our new task modal
  $scope.newTicket = function() {
    $scope.ticketModal.show();
  };

  // Close the new task modal
  $scope.closeNewTicket = function() {
    $scope.ticketModal.hide();
  };
})

.controller('TicketDetailCtrl', function($scope, $stateParams, Tickets) {
  $scope.ticket = Tickets.get($stateParams.ticketId);
})

.controller('AccountCtrl', function($scope) {
});

#5

Well, here i see two possible answers.
Thw first method could be in your createTicket function. When the function is called and the modal is closed, store the value of $scope.tickets.length and then push a new item like

$scope.tickets.push({
  name: ticket.name,
  id: length
});

this way every entry will have a unique correlational id.

The second method is just don’t store the id, because you don’t need to store that information if you don’t have to. If the ID of the ticket is important to you, just ignore what i’ve just said.

Greetings


#6

Cool, I will try the first one. This issue of not having an id is if a ticket was created with the same ticket.title, then I am guesstimating that the app would get confused when opening the ticket to view in detail if the view is attached the the .title which is not unique. With an .id, there would be a unique identifier, thus removing any confusion. Does this sound correct or did I just out myself on my noobness :slight_smile:


#7

Its ok, attaching one id to an entry is the most common behaviour when we work with big lists of items.
But with angular, depending on your app, you just can use $index to access the desired item, without referending it by name nor id.

Anyway, putting an id can be useful for other things so, nothing wrong with it.
Good luck with your app


#8

I was using id because I am a noob, but not as much anymore… :slight_smile:

The hell with the id…

I changed

<ion-item ng-repeat="ticket in tickets" type="item-text-wrap" href="#/tab/ticket/{{$ticket.id}}">

to this

<ion-item ng-repeat="ticket in tickets" type="item-text-wrap" href="#/tab/ticket/{{$index}}">

And it works so much better…seems cleaner too. Just for my own learning, can you describe how to put the id option into my controller, I’ve been messing with it for hours, I was even trying to do a ‘for loop’…

You can’t imagine how ecstatic I am right now. Thank you so much!!


#9

Sorry for the late answer, I had to sleep!
The use of $index on your ng-repeat looks very clean! Good Job.

I don’t fully understand what you mean by put the id option into my controller, you mean when you are in TicketsCtrl, and the user clicks over one of your tickets, go to another page with TicketDetailCtrl with that ticket id?

If its that, there are various ways, but the best one is by using $stateParams but I see that you’ve already done it, so i dont get what you mean (sorry)