Home » Mime-type validator in MEAN Stack

Mime-type validator in MEAN Stack

by Online Tutorials Library

Mime-Type Validator

In our previous section, we successfully added the image controls to store the image and previewed the image to the user as well. Everything is nice, but it would be nicer if we could also validate it to have a valid image. There is no built-in validator that would help us with that, so we will write our own one. We will write the validator in a separate file in the following way:

1) We will create a new typescript file in our post-create component and give it the name mime-type.validator.ts.

Mime-Type Validator

The mime-type validator will have the task of getting the value of control, which will be a file. After that, it read that file using that file reader again and then will check for that file’s mime type. We will write the logic for this together, so it will be a little more complex and advanced JavaScript.

2) All validators are just functions that read in the control value and return the information, whether valid or not. So, we will create a function using the export keyword. We will name it mime-type for better understanding. You can give any name to it.

Mime-Type Validator

3) Now, we need to pass the argument. We pass the control which is of type AbstractControl as an argument like as:

Mime-Type Validator

4) We also need to return something, and this will be an asynchronous validator because reading in that file with the file reader is an asynchronous task. A normal synchronous validator would simply return a JavaScript object where we have a key-value pair with our own error code and then a value for that error code or null. If the validator returns null, the value is treated to be valid otherwise, it’s invalid or fails. Now, for the asynchronous validator, it is almost the same, but the JavaScript object with the error code is wrapped by an observable or a promise. So, we will either return a promise or return an observable.

Mime-Type Validator

5) Both the promise and the observable are generics which mean that it is clear which value they will eventually yield. For the promise, that will be that JavaScript object, and in this object, we have any property, and we don’t care about the name. We just want to say it should have a property, and we do that with square brackets like this:

The [key: string] means this return type will have a property that can be interpreted as a string, and we don’t care about the name. The square brackets don’t indicate an array. It indicates that this is a dynamic property name.

Now, the value of that property will be anything, So, we can pass any value we want for that error code.

Mime-Type Validator

6) The generic type which we used for the promise is the same for the observable. This will be our function definition, so we will get an error because we are not fulfilling it right now. We are not returning a promise or an observable.

Mime-Type Validator

7) In the body of the function, we will extract the file in the following way:

Mime-Type Validator

In the above line of code, we will create a new constant and store the control’s value. We use “as File” to tell the typescript that the control’s value will be a file.

8) We will use the FileReader, so we will create a new object of FileReader like:

Now, we can use the filereader to read in that value of the file. Previously, we used the filereader.onload, but we now need onloadend that would not really work because, in this function, we need to return a promise or an observable and the filereader.onloadend is neither. This is the synchronous code that just registers a function.

9) The rxjs give us something that allows us to convert “filereader.onloadend = () =>{}” into an observable, and that is, we can create our own observable. For doing that, we will create a new constant for file reader observable and create our own observable by calling observable, and there is a static create() method.

Using the create() method, we can create our own observable from scratch.

10) Now, we will pass a function to the observable as an argument. Then again, this function automatically gets an observer that is passed in by rxjs, and it is of type observer.

Mime-Type Validator

11) We get an error in the Observer because it turns out to be a generic type, and the type will be the same JavaScript object which our whole validator will eventually emit.

Mime-Type Validator

12) In this observable, we will take our filereader and add the loadend event listener to it. There is another function that will get executed once the loadend event is done.

Mime-Type Validator

13) Now, we have the loadend event, and here, we want to emit a new value with the information to know that this is a valid file or not. We will do this inside this event listener because of that extra information. Before implementing this, we will go to the line after the listener, and here we will start that process by reading in the file as an array buffer:

Mime-Type Validator

It allows us to access the mime type. When it is done, addEventListener loadend will call the function passed in the event listener.

14) Now, we need to implement the function passed in the event listener. We will do mime type validation here. We will create a new array of 8-bit unsigned integers using Uint8Array in the following way:

Mime-Type Validator

In the above code, we used subarray(0, 4) to access a subarray from 0 to 4. It is the part that allows us to get that mine type.

15) Now, we need to read a certain pattern to get that file type, and that pattern is read in with a “for” In this loop, we will go through the array and extract some information from there.

Mime-Type Validator

16) Now, to extract information from there, we will create a new variable header that will initially be an empty string, and then in the form loop, we will attach something to the string, which will be the element we are currently looking for at in our loop.

Mime-Type Validator

We used toString(16) to convert the array element into a hexadecimal string in the above code.

17) After getting a hexadecimal string, we can switch that header because we will have a string that has a clearly defined pattern for the different file types.

Mime-Type Validator

In the above code, each case has a pattern that stands for certain file types like jpeg and png.

18) We have the isValid variable, and now we need to use the Observer to control the observable. So, we will check that our isValid property is true or not. If it is true, it will call the next function of the Observer to emit a new value, and the value will be null because we have to return null. If it is not true, we emit a different value that is a JavaScript object like this:

Mime-Type Validator

19) We will call the complete function of the Observer to let any subscribers know that we are done.

Mime-Type Validator

20) The only thing which we need to do is we need to return the observable by simply adding the following line of code:

Mime-Type Validator

After adding this line of code, we will have a valid file type validator.

21) We will now attach it with our form, so we will go back to our post-create component. We import the mime type validator in the following way:

Mime-Type Validator

22) We will add it in the image control not as a validator though but as an asynchronous validator in the following way:

Mime-Type Validator

Now, we are initializing that image in a way that we only accept images.

23) Now, we will go back to our post-create.component.html file and make sure that our preview will not only shown if we got a valid image preview value but we also want to check for the image validation like this:

Mime-Type Validator

We save all the files, go back to our angular app, and load an image and video.

Mime-Type Validator
Mime-Type Validator
Mime-Type Validator
Mime-Type Validator
Mime-Type Validator
Mime-Type Validator

So, everything is working well here. In the next section, we will learn about the server-side uploading.

Download Complete Project(Mime type validator.zip)


You may also like