Inspiration

We were inspired to create SplitJar because as roommates we have many things that we thought we could put this app to practical use with. Such as if one of us leaves the lights on, we have to put some money into a "Lights Left on Jar" However since it is comber-sum and difficult to carry cash, we didn't like the idea of a physical jar and thought it would be better if we could do this from our phones quickly and easily.

What it does

SplitJar allows users to create 'Jars' and and add other users to them via email. Once added, each person has the ability to see the balance of the jar, and to put money in when they need to. This allows users to set up different 'Jars' with things like goals, charge amount, etc. By using this the group within the jar can decide what they want to do when they reach their goal with the money they have collected.

How we built it

SplitJar is a four part system as of now, it has a Node.js Backend attached to a MongoDB database, an Angular.js front end web application, and an IOS application for phones. We started the project off with a lot of design and planning to make sure everything would go as smoothly as possible. With that in mind we created the Node.js Backed and began to tie the swift and Angular applications into the. This resulted in a nice stack that makes it very easy for the user to use, see, and enjoy.

Challenges we ran into

Making sure that the data types, and returns between four seperate pieces to this stack were all in sync and of the same types was no small feat, many times we had to scrap the current design for different things and recreate it in a way that was usable across the stack. A key time that this happened was when we began to use the XCode UI to write our swift code and realized that Swift was not going to play well with the javascript objects the way we were sending them. This lead to us having to recreate contracts between each of the four pieces of the stack. It also was difficult to build and design a backend that had all the endpoints and functionality which we needed.

Accomplishments that we're proud of

Fully finishing a backend in under twenty-four hours and seeing it come together with the other two pieces of the stack as we began to complete them was a very fulfilling and glorious moment. We had wished to make a small POC application and it began to go way passed that into a successful project that we are both very proud to have completed.

What we learned

How to create json requests in Swift and parse the data using stucts. A good example of this can be found in our code, it looks like this:

{
        let semaphore = DispatchSemaphore (value: 0)
        let parameters = "{\n\t\"username\": \"" + user + "\",\n\t\"password\": \"" + psw + "\"\n}"
        let postData = parameters.data(using: .utf8)
        var request = URLRequest(url: URL(string: "http://192.168.1.5:3000/api/v1/users/validate")!,timeoutInterval: Double.infinity)
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.httpMethod = "POST"
        request.httpBody = postData
        let task = URLSession.shared.dataTask(with: request) { data, response, error in
          guard let data = data else {return}
            let jUserFail = jUser(email: "null", name: "null", password: "null", balance: -1.0)
            let jusermessagefail = jUserRespose(message: "null", user: jUserFail)
            func getJson()->(jUserRespose?){
                do{
                    let juse = try JSONDecoder().decode(jUserRespose.self, from: data)
                    return juse
                }
                catch{
                    print(error)
                }
                    return jusermessagefail
            }
            let jMess = getJson()?.message
            let jUser = getJson()?.user
            if(jMess == "User found"){
                self.uFound = true
                self.gbName = (jUser?.name)!
                self.gbEmail = (jUser?.email)!
                self.gbPassword = (jUser?.password)!
                self.gbBal = (jUser?.balance)!
            }
           //print(jMess)
            let dataStr = String(data: data, encoding: .utf8)
          //print(dataStr)
          semaphore.signal()
        }
        task.resume()
        semaphore.wait()
    }

Although this code may not look like much, it was a great deal of work to create it functionally and deploy it onto an IOS device. We are also really proud of how we manage to create some of the endpoints in our Node.js backend using Express, we hadn't used express all that much, and were excited to see how it worked. This was some of our best results:

app.put('/api/v1/jars/updateCharge/:jarID/amount/:chargeAmount', (req, res, next) => {
  Jar.find({_id: req.params.jarID}).then(foundJars => {
    if(foundJars.length == 0) {
      res.status(404).json({
        message: "No jar with that Id exists"
      });
    } else {
      foundJars.forEach(jar => {
        jar.charge = req.params.chargeAmount;
        jar.save().then(result => {
          res.status(201).json({message: 'Succesfully updated the charge amount for the jar', jar: result});
        })
      });
    }
  });
});

All and all we were very proud of the work that we were able to accomplish and it made us excited to get to keep working on the project.

What's next for SplitJar

We hope to use SplitJar everyday within our own home, to keep on each other about things like leaving the lights on when you leave. We also hope to deploy it onto our own servers that we host so that we can allow other people to give it a run and see what they think.

Be sure to checkout the Backend/Web App and the IOS Swift App for the stack on github.

Share this project:

Updates