Sunday, July 31, 2016

An Example of Using Dart - forcemvc, MongoDB, and objectory, part 2

/lib/model.dart

part of controllers;

class Person extends PersistentObject {
//  String get collectionName => "Name";
  String get firstName => getProperty('first_name');
  set firstName(String value) => setProperty('first_name', value);
  String get lastName => getProperty('last_name');
  set lastName(String value) => setProperty('last_name', value);
  String toString() => "$firstName $lastName";
  Future<bool> isDuplicate() {
    Completer completer = new Completer();
    bool answer;
    objectory.initDomainModel().then((success) {
      objectory[Person].find(where.eq('first_name', this.firstName)
          .and(where.eq('last_name', this.lastName))).then((matches) {
        if (matches.length > 0) {
          answer = true;
        } else {
          answer = false;
        }
        completer.complete(answer);
      });
    });
    return completer.future;
  }
}

add(Person person) {
/*  objectory =
  new ObjectoryDirectConnectionImpl('mongodb://127.0.0.1/forceobject2',
      () {    objectory.registerClass(Person, () => new Person(),
        () => new List<Person>());  }, false); */
//  init();
  objectory.initDomainModel().then((_) {
    objectory.save(person);
  });
}


Future<Person> newPerson(String first, String last) {
  Completer completer = new Completer();
/*  objectory =
  new ObjectoryDirectConnectionImpl('mongodb://127.0.0.1/forceobject2',
      () =>      objectory.registerClass(Person, () => new Person(),
          () => new List<Person>()), false);
          */  //init();
  objectory.initDomainModel().then((_) {
    Person person = new Person()
      ..firstName = first
      ..lastName = last;
    completer.complete(person);
    //   objectory.close();
  });
  return completer.future;
}

Future<List<Person>> allPeople() {
  Completer completer = new Completer();
/*  objectory =
  new ObjectoryDirectConnectionImpl('mongodb://127.0.0.1/forceobject2',
      () =>      objectory.registerClass(Person, () => new Person(),
          () => new List<Person>()), false);
          */
//  List<Person> names = new List();
//  init();
  objectory.initDomainModel().then((success) =>
      objectory[Person].find().then((List<Person> people){
        completer.complete(people);
//        objectory.close();
      })
  );
  return completer.future;
}

Future<bool> isDuplicate(Person person) {
  Completer completer = new Completer();
  bool answer;
  objectory.initDomainModel().then((success) {
    objectory[Person].find(where.eq('first_name', person.firstName)
        .and(where.eq('last_name', person.lastName))).then((matches) {
      if (matches.length > 0) {
        answer = true;
      } else {
        answer = false;
      }
      completer.complete(answer);
    });
  });
  return completer.future;
}


/lib/controllers.dart

library controllers;
import 'package:objectory/objectory_console.dart'
;import 'package:forcemvc/force_mvc.dart';
import 'dart:async';
part 'model.dart';

init() {
  objectory = new ObjectoryDirectConnectionImpl(
      'mongodb://127.0.0.1/forceobjectory2', () =>
      objectory.registerClass(
          Person, () => new Person(), () => new List<Person>()), false);
}


@Controller
class MainControllers {
  @RequestMapping(value: '/', method: RequestMethod.GET)
  String index(ForceRequest req, Model model) {
    return 'index';
  }

  @RequestMapping(value: '/verify', method: RequestMethod.POST)
  Future<String> verify(ForceRequest req, Model model) {
    req.getPostParams().then((Map params) {
      init();
      String first = params['first_name'];
      String last = params['last_name'];
      newPerson(first, last).then((Person person) {
        model.addAttribute("person", person);
        //      return isDuplicate(person).then((bool match) {
        return person.isDuplicate().then((bool match) {
          if (!match) {
            return person.save();
          }
        });
      }).then((_) {
        return allPeople().then((List people) =>
            model.addAttribute("people", people));
      }).then((_) {
        model.addAttribute("message", "It works!");
        req.async('verify');
      });
    });
    return req.asyncFuture;
  }
}


Saturday, July 30, 2016

An Example of Using Dart - forcemvc, MongoDB, and objectory, part 1

This app is a simple idea... ask the user for his name, then check it against your records. If nothing on file matches, that name gets added to the database. A list of all the saved names also appears. I decided to use Ojectory because it works with data objects more directly as objects than mongo_dart does.

Since we're using Dart, the first step is writing the pubspec.yaml file. This file configures the app's dependencies on third-party packages. For the sake of sanity, we will specify exactly which versions to use. We only need two external packages, objectory for database access and forcemvc for a web architecture. What we need is something like

/pubspec.yaml


name: ForceMVC_Objectory2
version: 0.0.1
description: A simple console application.
dependencies:
  objectory: 0.3.21
  forcemvc: 0.8.5

You can use any project name and description you like, but you'll need the rest as is. The next step is to make a /bin directory in the root of our project. All that we will write there is the main.dart file. That file contains the main function, which is always the entry point. There we create a WebApplication object to configure and start the web server. main() also tells the user what web address will be used; however, the print statement has no actual affect on it.

/bin/main.dart


library ForceMVC_Objectory2;
import 'package:forcemvc/force_mvc.dart';
import '../lib/controllers.dart';

main(List<String> args) {
  print('Opening localhost:8080');
  WebApplication application = new WebApplication();
  application.start();
}

We will be using the default settings. That means that the views will go in a /views directory. We put two files there: index.html and verify.html. index.html has the form, and verify.html shows the results.


/views/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Force Objectory 2</title>
</head>
<body>
<form action="/verify" method="post">
    <fieldset>
        <label for="first_name">First name: </label>
        <input id="first_name" name="first_name" type="text" required>
    </fieldset>
    <fieldset>
        <label for="last_name">Last name: </label>
        <input id="last_name" name="last_name" type="text" required>
    </fieldset>
    <input id="btn" type="submit" value="Continue">
</form>

</body>
</html>
 

/views/verify.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Name List</title>
</head>
<body>
<p>{{message}}</p>
<p>Tried to add {{person}}</p>
<ul>
    {{# people}}
    <li>{{firstName}} {{lastName}}</li>
    {{/ people}}
</ul>

{{^ people}}
<h3>Empty List</h3>
{{/ people}}
</body>
</html>


{{person}} echoes the name the user entered. {{people}} is an updated list of all the names on file. "#" generates a list, and "^" means "if the list is empty". In the interest of space, the controllers and model code will be in the next post.