Seque is not working

I have parsed a json file with the following structure into a table view succesfully.

import Foundation

struct ActionResult: Codable {

    let data3: [Datum]

}

struct Datum: Codable {

    let actionGoal, actionGoalDescription, actionGoalImage: String

    let actions: [Action]

}

struct Action: Codable {

    let actionTitle: String

    let actionID: Int

    let select, completed, favorite: Bool

    let actionType, actionDescription, actionTips, actionImage: String

    let actionSponsor, actionSponsorURL: String

Now I am preparing a segue to a detail ViewController but is giving me an error.

 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

            performSegue(withIdentifier: "showDetail", sender: self)

       }

        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

            if let destination = segue.destination as? ActionDetailViewController {

                destination.action = result?.data3.actions[(tableView.indexPathForSelectedRow?.row)!]

Error description. Value of type '[Datum]' has no member 'actions'

Who can help me?

Answered by Claude31 in 709227022

You already posted the same question a moment ago… It is about segue, not seque.

Problem is

        destination.action = result?.data3.actions[(tableView.indexPathForSelectedRow?.row)!]

data3 is [Datum], not Datum. Hence, it has no actions property.

Which datum in data3 do you want to use ?

  • you have to define this index (take care it is consistent with the number of items in data3):

var indexData = 0

  • Set it somewhere in code (in didSelectRowAt or elsewhere)

  • Use it in prepare:

        destination.action = result?.data3[indexData].actions[(tableView.indexPathForSelectedRow?.row)!]

Note: when you paste code use "Paste and Match Style and the use code formatter tool:

import Foundation

struct ActionResult: Codable {
  let data3: [Datum]
}

struct Datum: Codable {
  let actionGoal, actionGoalDescription, actionGoalImage: String
  let actions: [Action]
}

struct Action: Codable {
  let actionTitle: String
  let actionID: Int
  let select, completed, favorite: Bool
  let actionType, actionDescription, actionTips, actionImage: String
  let actionSponsor, actionSponsorURL: String

var indexData = 0

//    Now I am preparing a segue to a detail ViewController but is giving me an error.
 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
      indexData = 0     // Initialise here or elsewhere, before segue.
      performSegue(withIdentifier: "showDetail", sender: self)
    }

  override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
      if let destination = segue.destination as? ActionDetailViewController {
        destination.action = result?.data3[indexData].actions[(tableView.indexPathForSelectedRow?.row)!]
Accepted Answer

You already posted the same question a moment ago… It is about segue, not seque.

Problem is

        destination.action = result?.data3.actions[(tableView.indexPathForSelectedRow?.row)!]

data3 is [Datum], not Datum. Hence, it has no actions property.

Which datum in data3 do you want to use ?

  • you have to define this index (take care it is consistent with the number of items in data3):

var indexData = 0

  • Set it somewhere in code (in didSelectRowAt or elsewhere)

  • Use it in prepare:

        destination.action = result?.data3[indexData].actions[(tableView.indexPathForSelectedRow?.row)!]

Note: when you paste code use "Paste and Match Style and the use code formatter tool:

import Foundation

struct ActionResult: Codable {
  let data3: [Datum]
}

struct Datum: Codable {
  let actionGoal, actionGoalDescription, actionGoalImage: String
  let actions: [Action]
}

struct Action: Codable {
  let actionTitle: String
  let actionID: Int
  let select, completed, favorite: Bool
  let actionType, actionDescription, actionTips, actionImage: String
  let actionSponsor, actionSponsorURL: String

var indexData = 0

//    Now I am preparing a segue to a detail ViewController but is giving me an error.
 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
      indexData = 0     // Initialise here or elsewhere, before segue.
      performSegue(withIdentifier: "showDetail", sender: self)
    }

  override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
      if let destination = segue.destination as? ActionDetailViewController {
        destination.action = result?.data3[indexData].actions[(tableView.indexPathForSelectedRow?.row)!]

The segue is now working but it does not show the right detail with the second section.

If I change the indexData = 0 to 1 it does, but then the first section does not work.

the first row in the second section is showing the detail of the first row of the first section

You did not tell anywhere you had several sections.

Correction has to take into account section as well as row.

But you say nothing on data3 nor on actions: do they depend on section ? how ?

If you show, we can tell you how to correct.

I use the actionGoal in the data model as a section:

// Table View Sections

    

        func numberOfSections(in tableView: UITableView) -> Int {

        return result?.data3.count ?? 0

            

            }

        func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {

            return result?.data3[section].actionGoal

        }

And then the tableView:

// Table View

    

        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        if let result = result {

            return result.data3[section].actions.count

        }

            return 0

}

        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

            let action = result?.data3[indexPath.section].actions[indexPath.row]

            let cell = ActionTableView.dequeueReusableCell(withIdentifier: "ActionCell", for: indexPath) as! ActionTableCell

                cell.ActionTitle.text = action?.actionTitle

                cell.ActionImage.image = UIImage(named: action!.actionImage)

                  return cell

            

}

        func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

            return 80

    }

    

    // This code is for the transfer to the next page

    

   

        func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

            

            index = 0

                        

            performSegue(withIdentifier: "showDetail", sender: self)

       }

        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

            if let destination = segue.destination as? ActionDetailViewController {

                destination.action = result?.data3[index].actions[(tableView.indexPathForSelectedRow?.row)!]

       }

OK, that clear (please note how more readable is code when pasted as Paste and Match Style and when code formatter is used:

// Table View Sections
    
        func numberOfSections(in tableView: UITableView) -> Int {
        return result?.data3.count ?? 0
            
            }
        func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
            return result?.data3[section].actionGoal
        }

// Table View
    
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if let result = result {
            return result.data3[section].actions.count
        }
            return 0
}

You just have to change as follows:

        func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            
            index = indexPath.section    // <<--
            performSegue(withIdentifier: "showDetail", sender: self)
       }

        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if let destination = segue.destination as? ActionDetailViewController {
                destination.action = result?.data3[index].actions[(tableView.indexPathForSelectedRow?.row)!]
       }

You could also write simply (no index)

                destination.action = result?.data3[(tableView.indexPathForSelectedRow?.section)!].actions[(tableView.indexPathForSelectedRow?.row)!]
Seque is not working
 
 
Q