Lucid Projects

Blog - Day to day mumblings...
Questions - Collection syncing

Questions - Collection syncing

29 Sep 2020 - Jake Sherwood

Dada.art - Collaborative art Questions - Collection syncing

Questions - Collection syncing

This project was a deeper exploration of Express and Socket.io. We were tasked to send more that one thing between the server and clients.

For another class I needed a way to take some user input and create something from it. So I decided to use this project as an opportunity to build that.

Less artsy than maybe I would have liked initially, I am happy with how it turned out and definitely learned a lot in the process.

New Things
1) Using Javascript to create an interesting form UI
2) Use of the spread operator
3) Use of a set to get unique values
4) Typewriter Text - Animations without jQuery. I was especially happy about this one
And more…

Task Create a curated experience for a group.

Concept Develop a series of questions asked in a way that hopefully had participants answer with certain types of words. E.g. nouns, verbs, adjectives, adverbs etc.

I take these words split them into single word strings and push them into various arrays which are then sent out the server and back to each client.

There is also a counter for the number of participants as well as the number of participants whom have answered the questions. Socket calls keep both those counts incrementing accordingly.

participants counts

I was sending four separate arrays, from the answers, in one JSON data object. Sorting that back out and adding to the client arrays took me quite a while.

This is what I finally ended up with. I’m sure there is a cleaner way to do this.

function receiveData(data) {
		// get length of data received - count keys in the data object
		var dataCount = Object.keys(data).length;

		function cleanArrays(rArray, lArray) {
			// array for pushing received data to
			let result = [];

			for (var i in rArray)
				result.push(rArray[i]);

			// set it to sring and split it on comma
			let resultsString = result.toString();

			//then add seperate values to shared local array
			let tempArr1 = resultsString.split(",");
			for (i = 0; i < tempArr1.length; i++) {
				lArray.push(tempArr1[i]);
			}
		}

		// loop through data object received
		for (let j = 0; j < dataCount; j++) {
			switch (j) {
				case 0:
					cleanArrays(data.arr1, feelings);
					break;
				case 1:
					cleanArrays(data.arr2, objects);
					break;
				case 2:
					cleanArrays(data.arr3, loves);
					break;
				case 3:
					cleanArrays(data.arr4, tech);
					break;
			}
		}

As soon as I got to that solution I suddenly realized another problem I had been blind to. In the current form it would just be adding to the array and then sending it on. So it would duplicate the data as it sent each time… ugh.

Luckily the spread operator and a set saved the day. This thread helped get me going.

On the receiving client end, I use the spread operator “…” to push data into a “set” to get unique values. First time using that operator so that was fun to figure out.

			// push them into a set for unique values to shared local array
			// also first time using the 'spread' oporator yay
			let lArrayTemp = [...new Set(lArray)];

			// finally set unique values to shared
			lArray = lArrayTemp;
		}

Adding this bit before my switch case allowed me to clean my local arrays when data was received.

Also I wanted a nice clean UI. So I spent a little time looking at some examples. I settled on this CodePen. It used javascript and simple CSS to produce a simple and clean UI/UX. I really liked the effect, and the progress as the questions were answered was nice. With minor modifications I had it working for my needs and my web app suddenly looked WAY better.

The ultimate goal of taking this data and sharing it between participants / clients, was to create random sentences from all the words all the participants just shared.

I found a good randomly generated sentence structure that I tried to follow here.

I thought it would be a really nice effect to have the sentences be revealed as if they were being typed. This Stack Overflow gave me the basis but it took a bit of finagling to get working.

Basically since I was creating my sentences and containers for them dynamically I had to then get the width of my newly created div / span before I could animate it. Also in this process I learned about the Velocity lib. Which allows for better performance when using animate vs jQuery. In this class I’ve been making a conscious effort to use jQuery less so it was nice to find that I could use this other lib instead.

I also adapted Marcel’s randomStyle code from her chat app to have the sentences spaced randomly throughout the window.

Finally the updateAnswerCount function on the server is listening for all answers and if all participants have answered it emit’s the allAnswered event to all clients which calls the random sentence reveal.

        function updateAnswerCount() {
            console.log("ran update answerCount");
            io.emit('pollAnswers', answerCounter);
            //  socket.broadcast.emit('pollUsers', connectCounter);
            console.log("ran updateAnswerCount from updateAnswerCount " + answerCounter);

            if(connectCounter > 1 && connectCounter == answerCounter)  {
                io.emit('allAnswered', true);
                console.log("all users answered");
            }


        }
 

Questions - 2 participants


Things to Fix
1) Sentences too close to each other.
2) Sentences too far to the right. Being drawn off the screen.
3) Better questions to get the results / word types I want.
4) Update responsive CSS and enable touch for mobile.
5) Move all js to a separate file. I was getting errors when I tried to move the js but didn’t have time to debug it.

Github code here.

categories: liveweb

join me on this crazy ride. enter your email:

contact [at] jakesherwood [dot] com

contact me if you'd like to work together