chsn
chsn

Reputation: 21

Play 2.0 javaToDo tutorial doesn't compile

I'm trying to follow the Play2.0 JavaToDO tutorial and for some reason it just doesn't want to work. Have looked through stackoverflow and other online resources, but haven't find an answer to this and it's driving me crazy.

Attached code of the Application.java

package controllers;

import models.Task;
import play.data.Form;
import play.mvc.Controller;
import play.mvc.Result;

public class Application extends Controller {

static Form<Task> taskForm = form(Task.class);

  public static Result index() {
    return redirect(routes.Application.tasks());
  }

  public static Result tasks() {
      return ok(
        views.html.index.render(Task.all(), taskForm));
  }

  public static Result newTask() {
      return TODO;
  }

  public static Result deleteTask(Long id) {
        return TODO;
      }

}

Attached code of the Task java

package models;

import java.util.List;
import javax.persistence.Entity;

import play.data.Form;
import play.data.validation.Constraints.Required;
import play.db.ebean.Model.Finder;
import play.mvc.Result;
import controllers.routes;

@Entity 
public class Task {


  public Long id;
  @Required
  public String label;


  // search
  public static Finder<Long,Task> find = new Finder(
            Long.class, Task.class);

  // display tasks
  public static List<Task> all() {
      return find.all();
  }

  // create task
  public static void create(Task task) {
      task.create(task);
  }

  // delete task 
  public static void delete(Long id) {
      find.ref(id).delete(id);
      // find.ref(id).delete();
  }

  // create new task
  public static Result newTask() {
      Form<Task> filledForm = taskForm.bindFromRequest();

      if(filledForm.hasErrors()) {
        return badRequest(
          views.html.index.render(Task.all(), filledForm)
        );
      } else {
        Task.create(filledForm.get());
        return redirect(routes.Application.tasks());  
      }
    }
}

I get a compile error on Task.java on the line static Form<Task> taskForm = form(Task.class);

As I'm working on eclipse (the project is eclipsified before import), it's telling me that taskForm cannot be resolved and it also underlines every play 2 command e.g. "render(), redirect(), bindFromRequest()" asking me to create a method for it. Any ideas how to solve the compilations error and also how to get Eclipse to recognize the play2 commands?

EDIT:

updated Application.java

package controllers;

import models.Task;
import play.data.Form;
import play.mvc.Controller;
import play.mvc.Result;

public class Application extends Controller {


    // create new task
    public static Result newTask() {
      Form<Task> filledForm = form(Task.class).bindFromRequest();

        if(filledForm.hasErrors()) {
          return badRequest(
            views.html.index.render(Task.all(), filledForm)
          );
        } else {
          Task.newTask(filledForm.get());
          return redirect(routes.Application.tasks());  
        }
    }


    public static Result index() {
        return redirect(routes.Application.tasks());
    }

    public static Result tasks() {
        return ok(
        views.html.index.render(Task.all(), taskForm));
    }

    public static Result deleteTask(Long id) {
        return TODO;
    }

}

Updated task.java

package models;

import java.util.List;
import javax.persistence.Entity;
import play.data.Form;
import play.data.validation.Constraints.Required;
import play.db.ebean.Model;
import play.db.ebean.Model.Finder;
import play.mvc.Result;
import controllers.routes;

@Entity 
public class Task extends Model {

  public Long id;
  @Required
  public String label;

  // Define a taskForm
  static Form<Task> taskForm = form(Task.class);

  // search
  public static Finder<Long,Task> find = new Finder(
            Long.class, Task.class);

  // display tasks
  public static List<Task> all() {
      return find.all();
  }

  // create new task
  public static Result newTask(Task newTask) {
     save(task);
 }

  // delete task 
  public static void delete(Long id) {
      find.ref(id).delete(id);
      // find.ref(id).delete();
  }

}

Upvotes: 2

Views: 4755

Answers (6)

Ravindra Mijar
Ravindra Mijar

Reputation: 1312

I had a problem with the scope of the variable static Form taskForm; It was in default scope. When I changed it to public static that error went.

I tried an expense management system instead of the task list. Conceptually it was very similar - list expenses, add expenses etc. I used a SQLite3 database instead of the default H2.

in application.conf file These were some of the other changes I had to do -

# Ebean configuration
# ~~~~~
# You can declare as many Ebean servers as you want.
# By convention, the default server is named `default`
#
ebean.default="models.*"       <<<<<<<<---- uncommented this.

# Evolutions
# ~~~~~
# You can disable evolutions if needed
evolutionplugin=disabled        <<<<<<<<---- uncommented this.

evolutions plugin was trying to create a table by running an auto query based on the models.Expense class I had created. On disabling this plugin, I was able to continue.

Another thing to note was - I had to create the table exactly the same way as my Expense class was defined. The order and data type of the variables declared in the Expense class was same as the database table.

db.default.url="jdbc:sqlite:<absolute path including DB name>"

I wanted to first check whether it can list the expenses from the table or no. So, I commented out these lines from the Application.newExpense() function.

public static Result newExpense() {
        Form<Expense> filledForm = Application.expenseForm.bindFromRequest();

        if(filledForm.hasErrors()) {
            //return badRequest(views.html.index.render(Expense.all(),Application.expenseForm));
            return null;
        }
        else {
            Expense.create(filledForm.get());
            //return redirect(controllers.routes.Application.expenses());
            return null;
        }

    }

This is how my index.scala.html looks like -

@(expenses: List[Expense] , expenseForm: Form[Expense])

@import helper._

@main("Expense Management System") {

    <h1>@expenses.size() expense(s)</h1>
    <ul>
        @for(expense <- expenses) {
            <li>
                @expense.id 
                @expense.category 
                @expense.description 
                @expense.amount
            </li> 
        }
    </ul>
    <h2>Add a new expense</h2>
    @form(routes.Application.newExpense()) {
        @inputText(expenseForm("label"))

        <input type="submit" value="Add">

    }

}

I didn't add the sqlite3 dependency in the Build.scala file's appDependencies section, as I read here that I don't have to add the DB dependency if I add its jar file in the lib/ directory.

 val appDependencies = Seq(
        jdbc,
        // Add your project dependencies here,
        //"sqlite3" % "org.sqlite.JDBC" % "3.6.20",
        javaCore,
        javaEbean
    )

Upvotes: 0

Steffen Friedrich
Steffen Friedrich

Reputation: 1

You have to install Scala plugin for Eclipse to solve this http://scala-ide.org/download/current.html and sometimes it is necessary to refresh the eclipse project.

Cheers!

Upvotes: 0

tagneha
tagneha

Reputation: 53

I also received this error and gone all through the net, but the error remained there. one of the quick fix solution i got is : Use

static Form taskForm =Form.form(Task.class);      instead of 

 static Form taskForm=form(Task.class);

in your application.java file

Hope this solves your problem.

Upvotes: 1

Mark Locklear
Mark Locklear

Reputation: 5355

I am working though this tutorial...

https://github.com/jamesward/play2torial/blob/master/JAVA.md

...and was getting a similar error as listed above working with version 2.0.1 or Play. I am working though the same tutorial with version 2.0.4, and I am NOT seeing the error. So give the latest version of Play a try.

Upvotes: 0

Mashrur
Mashrur

Reputation: 535

Try putting these import statements on Application.java [original/ not updated one]:

import play.data.*;
import static play.data.Form.*;

Upvotes: 2

ndeverge
ndeverge

Reputation: 21564

I think that you've actually made somes mistakes:

  1. taskForm cannot be resolved in your Task class since it is declared in your controller
  2. your view will be compiled by sbt (ie the play console) when you'll run the app. So the render method will be available after the compilation will be fine (you'll have to do a refresh on Eclipse)
  3. same issue for redirect
  4. bindFromRequest() is not available since taskForm can not be resolved (cf 1.)

EDIT:

I just saw that there is a newTask() method in the Task class, and this method should be something similar to this:

In the Task class (which should extends play.db.ebean.Model):

 // create new task
 public static void newTask(Task newTask) {
    save(newTask);
}

And in your controller:

  // create new task
  public static Result newTask() {
    Form<Task> filledForm = taskForm.bindFromRequest();

    if(filledForm.hasErrors()) {
      return badRequest(
        views.html.index.render(Task.all(), filledForm)
      );
    } else {
      Task.newTask(filledForm.get());
      return redirect(routes.Application.tasks());  
    }
}

EDIT 2:

     

// create new task
      public static Result newTask() {
        Form<Task> filledForm = form(Task.class).bindFromRequest();

        ...
    }

Upvotes: 0

Related Questions