Ceci n’est pas une gallerie

The joke here is that I am in fact a ginormous nerd across several axes, including the arts. For those not familiar, there is a famous work of art called “The Treachery of Images” that is a picture of a fairly generic smoking pipe, underneath which is written “ceci n’est pas une pipe.” From the French, this means “this is not a pipe.” Of course it isn’t, it’s a picture of a pipe, but that’s not how most people would think of it; most people would look at it and say well, yes, of course it’s a pipe, what do you mean it’s not a pipe? And when it’s explained, the logic is clear, but it’s still not the common first reaction unless you’ve had the whole Surrealism movement lecture in art history and, of course, you’re a giant nerd.

Anyway.

Ceci n’est pas une gallerie, because this is not a gallery of images. Could I have encoded a gallery  into which a person could upload images? Probably, but I was a bit crunched for time and also not entirely sure I wanted to do that, regardless. The goal of this project is not and has never been to display the images; there are numerous other services for that. Rather, the goal of this project was to serve as sort of a card catalog for images with fields for the style, the medium, the number of hours it took to make it, and the subject of the artwork. Eventually, with more practice, I plan to introduce a user model so that the gallery project can serve as a sort of skill list, and a user’s profile page can display hours spent working in each medium they prefer. Other stretch goals include a randomizer function where anyone can click a button and get a randomly generated set of prompts for medium, style, or subject. The whole project came out of a desire to code that randomizer, specifically, because I was practicing with my art supplies and wanted prompts. You see what I mean by scope shift?

The project requirements involved a Rails back-end and a React/Redux front-end, and in the beginning I made the full thing in Rails because I wanted to see if I could get the method to show a user’s time spent in a particular medium functioning. I didn’t have to build the full Rails front-end, I suppose, but I did anyway and in a separate repository, plus I decided I could use the practice in Rails. Having gotten the method working, I created the primary working repository and built up the Rails back-end, then started working on the React/Redux front end. That proved to be… more complicated.

Among the things I learned working on this project: did you know the FastJSONAPI serializer won’t play nicely with React/Redux? I do now! I used the ActiveModelSerializer instead, as advised by a project walkthrough kindly provided by the school. Being absolutely candid: I hate JavaScript and all its frameworks. I find it clunky and prone to bloat and have for years if not decades, but building out the project did help me become familiar with its workings, as I presume was the goal. 

In coding the various components and containers I became familiar with a stateless component as opposed to a component with state. Stateless components are more likely to be display components, action components, anything that doesn’t need to maintain a state set at construction (and rendering, eventually). Conversely, if it needs to maintain a state, such as any containers in which anything is rendered (not the display styling itself, but the container that feeds the data to the display) or any input form, obviously that becomes a Class component with a state in the constructor method. The constructor method need not be explicitly stated in the code, but the state does need to be there.

I also got considerable practice in passing through props, finding those props in the Redux dev tools or by logging them to the console, figuring out which components needed which props, and how to access them and when and why. One particular sticking point was the usage of ‘props’ vs ‘this.props’: props are passed to all components but if it is a functional component, there’s no need to use ‘this’, referring to that specific instance of a class component. It took me an appallingly long time to figure that out. I also got some practice in using mapStateToProps (feeding information from the state of store to the component at hand via props) and mapDispatchToProps (dispatching action functions to the store so they can be used to manipulate the data, to change the state).

And I made a lot of mistakes. The usage of the wrong serializer gem was probably the biggest one, but there were still a number of mistakes made, many of them involving naming functions. Many of those involved thinking I knew what I was doing, building out shells of many files, and then getting confused which one was which when I had endless number of ‘Gallery’ and ‘Galleries’ files floating around. Nothing smacks down careless arrogance like having to delete half your files because you’ve lost track of which was which and start over, with proper build-test-build more form.

And still, there’s been a considerable amount of scope creep and scope shift. I’m going to have to consider what I want out of this, although I still think a more informational file-cabinet type app is what I want, rather than a display app of the artwork itself. I left out the URL field of the at-this-point final product deliberately, not wanting to come up with a number of fake URLs for demonstration purposes and since the artwork described comes from my own artwork, most of which I haven’t uploaded anywhere. I could, in future versions, change the URL field to a location field and include either a URL or a description of whether the artwork is in a gallery, in a portfolio folder somewhere, on a parent’s fridge door. I’ve considered adding a field for Have/No Longer Have, because some of my artwork I’ve sent off to friends or family, and in the case of more professional artists they might have sold a piece. All things to consider for future versions, but for now this is a simple, working non-gallery app, and I’m pleased with how it’s made and how much I’ve learned by making it.