Polyglot Programming: TypeScript, Go, & Rust

Projector Operations in TypeScript



Polyglot Programming: TypeScript, Go, & Rust

Check out a free preview of the full Polyglot Programming: TypeScript, Go, & Rust course

The "Projector Operations in TypeScript" Lesson is part of the full, Polyglot Programming: TypeScript, Go, & Rust course featured in this preview video. Here's what you'd learn in this lesson:

The Primeagen walks through implementing the TypeScript Projector CLI application's add, remove, set, and get operations. A brief discussion regarding the basename and dirname utilities is also covered in this segment.


Transcript from the "Projector Operations in TypeScript" Lesson

>> Hi everyone, feel good about those. Right, I assumed set value remove value probably shouldn't print anything. We don't want them to, we could technically make it like set value could return the old value that it's overriding. Remove value could return the value that it's removing, right? We could do those we could print them out, but I'm not sure how useful those kinds of things are.

Which one do we wanna start with? Get value or get value all? I think getValue is probably a little bit more fun. It's a little tricky. So let's do that one. What are some things we're gonna have to use? Well, if you're not familiar, there is definitely going to be some kind of file popping going on.

And how does node handle this? Well, there's a variety of ways we can do right? We could technically use something like path.join and do that, right? We could join with debug and that would produce a new path that is effectively walking up it. A kind of, here, I'm gonna have to go up here and paste that in and go fs path g, there you go.

Another method that's just already on path is called a base name, and dirname. So if you're not familiar with those ones, those are kind of Unix II style items here. We can actually just check this out right now. So I can go like this, dirname/foo/bar/baz will produce foo bar.

So that's really what we're looking for. And base name of course, if you did the exact same thing, foo/bar/baz just produces baz, right? So these are cool little utilities. If you don't know about them, you should know about them, they're fantastic. I find that you end up using them a lot if you're just trying to get something quick done, so there we go.

So we can use dirname as a way to walk this. But what happens what's dirname, how exactly does dirname work? And my guess is it probably works a lot like the Unix Kind of style. So we can just discover what happens at the very end, right? What is the dirname of slash?

Well it's just slash, right? So that means we're gonna run into a case where at the end of using this, the next directory we need to check is the directory we've already checked. So we just kind of need to make sure we keep track of that. And that's it, awesome.

So let's go like this, let curr = this.config.pwd, awesome. And now we're gonna use the greatest loop of all time known as the do while loop. All right, I think that this is just the most beautiful ever. And I'm gonna do this, I'm gonna have a previous just because I want to be able to just have it inside the while condition.

I could do a next right here and do a break inside of it but why not just have while curr does not equal previous? Does that look good? Yeah. So, let's do this, it should be pretty straightforward, right? One thing I do love about JavaScript is that their recent addition of these, the nollie, coalescing operator, whatever you wanna call it, I think I call it the Elvis operator at 1.0.

I can do something like this, value equals this.data.projector. And then we're gonna use, obviously we start off with our path so I can curr and then I can give it that sweet, question dot. I love it. It's fantastic. And then give it a key, right? So if there's a value here, we should probably use that value, right?

So if value, well, we'll go like this let out equals undefined and it can also be a string and go out equals value. By the way just kind of a personal thing I never, I don't like to return in the middle of things I find that it often leads to harder to debug problems.

So I just do that hit with a nice little break cuz that's the end of that and return out. Personal building, kind of thing. So, now we go like this, const next = path.dirname, passing the current and then go previous = current, actually we don't even need to do the next, right?

And then current equals, paste that in, sorry, that was from a previous testing time. There we go. We just move everything forward. If we've done this all correct, we should hopefully break out of this loop. If I haven't done this correct, we're gonna be spinning in circles for a long time.

And then maybe I'll have to do some sort of print debugging. It'll be a lot of fun. Great times. Let's see. Awesome. So there we go. We have everything we kind of want right here. I think that's good, everyone good with this one? Shall we move on? I think we shall.

All right, so I'm just gonna copy this code and let's do get value all. Now, theoretically we could create some sort of containing, some sort of almost iterator like method to be able to walk these paths and do all of this for us. And so that way, we don't have to duplicate this logic, but it's just different enough that it's kind of painful to try to make all these things work.

You kind of get into goofy interfaces. So we're just gonna do this nice, the old fashioned way. So I wanna do out equals that, out will be returned to down here, but there is one small problem. Now remember, the present working directory is our most specific directory, that's the values we definitely want the most.

The slash directory or Windows is C colon slash something like that the other direction slash. That is our least specific values. So we wanna make sure we always have the most specific values being used, not the least specific values being used. So if I were to simply walk this directory and just merge the map over and over again we'd get a, what would that be?

That'd be like a leftmost merge. We want a rightmost. Merge, we want to go the other direction. And this is backwards for you. So I just did backwards hand gestures for both for you guys, you know, you get the idea. So let's walk the path. We'll put it all together, and then we'll produce, then we'll just reverse the array.

We'll keep it simple, very procedural, very easy so we go like this const paths equals an array, seems pretty simple, right? We'll do a nice, I will again, we'll use the greatest loop known to man, do while loop I don't know if you know this Past. Push current, fantastic and we'll just do that and then at the end we can use the old paths.reverse, right?

And now we have all these, I'm sure we could have done this in a more clever fashion but no need to be clever around here we're just trying to program it so it's the most obvious I'll try to do something similar in the other languages. So you can just see, obvious as opposed to, too clever.

All right, so reverse we're gonna just do a nice little forEach right here, or we can use the greatest thing of all time, that always leaves the bug a nice reduce. So let's do an accumulator and of course the current path and we can do that erase then that thing and just return this.

Nothing is better. Don't you just love debugging these ones, I just love it. It's just so fantastic because you don't even know when it's going to return out the value, you don't know when it's going to be the final value, just so much fun. So let's do that let's go return acc.

And now what we need is just simply check to see if there is an object in this location, and then we just simply can merge it into the map and we call it a day. So, there's some different ways we could do this. We can go const value = this.data.projector and we can use the path to check if there is a value at this location.

We could just simply do a object.assign and we could pass in our acc and then have our value, right? That's just simply gonna assign it on top and we're going from left to right in our directory structure, right? So we know that we're gonna get the least specific to the most specific.

So if we override something not a big deal, right? And of course, I'm in the wrong language here. Wait, what language is this? There we go, that's the language. There we go. We have it, awesome. So theoretically, our get all value should work. Now we can start testing this, but I'm just gonna finish this off and go all the way to the end.

So let's do set value, set value should be pretty straightforward set and delete a really, really fast, right? So let's just do that. If I can just do a simple let dir = equals this.data.projector, and then pass in this.config.present working directory. If directory doesn't exist, well we can just take this.

Put it over here? And I can just create a new object, fantastic and of course set dir equal to that as well. And just do a nice dir key = value, fantastic, that's really all we need to do, right? Cuz at this point the data is kept within our object.

We know it, so when we call save later on, it's going to already have all this data they're, fantastic. I'm positive there's a nicer way to do this but this is what I always end up doing. Though it has a really nice convention for this, I think that is really slick Russ has a really slick convention for working with maps or this types of objects.

I know we're just using a simple object. We could have used a map. Is there any benefit to using a map? I'm not sure if we're gonna get much benefit, same operations, right? I'm gonna have to do a get on it. It'll be undefined. Do a set on it.

You really save anything? I don't know. So there we go. Let's grab that and we'll do pretty much the exact same thing here except the only difference is that if it exists we need to do something, right? So I'll just take that out, grab the key, grab the present working directory, if this thing does exist.

Well then, let's delete. We can even const this one, right? So let's just delete out dir key. There we go. We're gonna just remove this entry from our object. Fantastic, we've done it. We now pretty much have our entire API in TypeScript done at this point. And a few tests are probably in order.

So we can jump on that now and make sure everything works before we finish off the program by doing the printing out, by doing the saving and kind of the rest of the operations.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now