Ways to confirm if a user has previously participated in a poll?

SCENARIO:

At present, I am storing an array of objects within the User model to track all the votes cast by the user.

Here is a glimpse of the model structure:

var schema = new Schema({
    firstName: {type: String, required: true},
    lastName: {type: String, required: true},
    password: {type: String, required: true},
    email: {type: String, required: true, unique: true},
    polls: [{type: Schema.Types.ObjectId, ref: 'Poll'}],
    votes: [{
      poll: {type: Schema.Types.ObjectId, ref: 'Poll'},
      choice: {type: Number}
    }]
});

Whenever a user casts a vote, the following method in the service gets triggered:

voteOn(poll: Poll, userID: string, choice: number) {
        UserModel.findById(userID, function (err, user) {
          user.votes.push({poll, choice });
          const body = JSON.stringify(user);
          const headers = new Headers({'Content-Type': 'application/json'});
          const token = localStorage.getItem('token')
              ? '?token=' + localStorage.getItem('token')
              : '';
          return this.http.patch('https://voting-app-10.herokuapp.com/user'+token, body, {headers: headers})
              .map((response: Response) => response.json())
              .catch((error: Response) => {
                  this.errorService.handleError(error);
                  return Observable.throw(error);
              })
              .subscribe();
        });
    }

This method essentially records the poll and choice selected by the user in the votes array.

However, my issue lies here:


ISSUE:

Upon loading the polls, I aim to display the ones where the user has already voted with their selections pre-selected, while also preventing them from voting again.

How can I achieve this functionality?

Below is the method from the service that fetches the polls:

getPolls() {
        return this.http.get('https://voting-app-10.herokuapp.com/poll')
            .map((response: Response) => {
                const polls = response.json().obj;
                let transformedPolls: Poll[] = [];
                polls.reverse();
                for (let poll of polls) {
                    transformedPolls.push(new Poll(
                        poll.title,
                        poll.choice1,
                        poll.choice2,
                        poll.counter1,
                        poll.counter2,
                        poll.user.firstName,
                        poll._id,
                        poll.user._id,
                        )
                    );
                }
                this.polls = transformedPolls;
                return transformedPolls;
            })
            .catch((error: Response) => {
                this.errorService.handleError(error);
                return Observable.throw(error);
            });
    }

And here is the corresponding HTML snippet for a poll component:

<article class="panel panel-default">
    <div class="panel-body">
      {{ poll.title }}
      <br>
      <br>
      <form #form="ngForm">
        {{ poll.counter1 }} votes <input type="radio" id="{{ poll.choice1 }}" name="my_radio" value="{{ poll.choice1 }}" (click)="onChoice1(form)">  {{ poll.choice1 }}
        <br>
        {{ poll.counter2 }} votes <input type="radio" id="{{ poll.choice2  }}" name="my_radio" value="{{ poll.choice2 }}" (click)="onChoice2(form)">  {{ poll.choice2 }}
      </form>

    </div>
    <footer class="panel-footer">
        <div class="author">
            {{ poll.username }}
        </div>
        <div class="config" *ngIf="belongsToUser()">
            <a (click)="onEdit()">Edit</a>
            <a (click)="onDelete()">Delete</a>
        </div>
    </footer>
</article>

Answer №1

There are various approaches you can take to achieve this task.

To maintain the current data model, the key is to compare the poll.id with the user.votes[pollIndex].id and disable input on the poll if they match. Although I have experience with ReactJS, I may not be able to provide guidance on how to implement this in Angular.

If I were leading this project, I would consider creating a new MongoDB schema named Vote or UserPoll:

{
    user: {type: Schema.Types.ObjectId, ref: 'User'),
    poll: {type: Schema.Types.ObjectId, ref: 'Poll'},
    choice: {type: number}
}

When a user wishes to participate in a poll, a new UserPoll object can be created with the current user and poll. Subsequently, all UserPolls involving the current user can be retrieved and filtered based on whether a choice has been made or not.

I hope this explanation clarifies the process for you.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How to disable typescript eslint notifications in the terminal for .js and .jsx files within a create-react-app project using VS Code

I'm currently in the process of transitioning from JavaScript to TypeScript within my create-react-app project. I am facing an issue where new ESLint TypeScript warnings are being flagged for my old .js and .jsx files, which is something I want to avo ...

The type 'TaskListProps[]' cannot be assigned to type 'TaskListProps'

I'm struggling with handling types in my TypeScript application, especially with the TaskListProps interface. export default interface TaskListProps { tasks: [ { list_id: string; title: string; description: string; status ...

Optimal approach for securely managing API credentials within Angular 2+ applications

I am facing a dilemma with my app that uses Google OAuth for authentication. I have stored my Google client id and secret in the environment.ts file of my Angular project. However, I do not want this sensitive information to be exposed if I publish my code ...

What is the reason my Angular attribute is only updated when triggered by a postMessage() method from my iframe?

I am working on a project where I have an attribute named counter that needs to increment by 1 every time a button within an iframe is clicked. To see the code, you can visit: https://stackblitz.com/edit/angular-fznrnf?file=src/app/app.component.ts The c ...

Transformation occurs once you subscribe to an observable entity

Within the x.component.ts, I initiate the getSomething() method from y.service.ts. Since this method returns an observable, I subscribe to it. However, I encounter a peculiar issue where an object with 4 elements, one being an array of number arrays (numbe ...

Find the mean value in Mongodb for entries where the value exists

I am attempting to determine the average rating only if the rating is not equal to 0, as the default rating is set at 0. This is causing an inaccurate calculation of the rate. .aggregate([ { $match : { id : sessionId }}, { ...

Aurelia TypeScript app experiencing compatibility issues with Safari version 7.1, runs smoothly on versions 8 onwards

Our team developed an application using the Aurelia framework that utilizes ES6 decorators. While the app works smoothly on Chrome, Firefox, and Safari versions 8 and above, it encounters difficulties on Safari 7.1. What steps should we take to resolve th ...

How can you prevent the keys from being read-only when mapping onto a type?

Here's a common query: How can I change keys from readonly to writable when using a type that is Readonly? For example: type Foo = Readonly<{ foo: number bar: number }> type Bar = /* What's the method to duplicate the Foo type, but w ...

Strapi database client has a notable absence of MongoDB

What is the reason for MongoDB not being included in the create-strapi-app installation process? https://i.sstatic.net/WeOVi.png ...

Adjusting the background color of the custom input range thumb when the input is disabled

I've customized the input thumb on my range slider, and I'm looking to change its color when it's disabled. I attempted adding a class to the thumb like this: input[type=range]::-webkit-slider-thumb.disabled and also tried adding the disa ...

Mongodb and Atlas encountered an issue with authentication, displaying the error message: 'Authentication failed.', with error code 8000

Unfortunately, I've attempted to follow this solution without success. A critical error has emerged while working with Mongodb + Atlas: MongoError: bad auth Authentication failed. at /Users/cyrus/Documents/Code/01. Code/Franklin-ford/franklin-f ...

Error: Missing npm install -g @angular/cli@latest package in devDependencies section

ng build is causing an issue that The error reads: Unable to Find npm install -g @angular/cli@latest in devDependencies. When I attempt to start the application using npm start, it works fine. However, while trying to build a file, I encounter this er ...

Retrieve a specific portion of the document by utilizing the $or operator in Mongoose MongoDB

User.find({ $or:[ {'userSetData.name': { $regex: new RegExp( searchTerm ,'i') }}, {'local.email': { $regex: new RegExp( searchTerm ,'i') }}, {'google.name': { $re ...

Unknown value: '$first'

Looking to extract the first item from an array and add it to its own object, I came across a function called $first that does just that. You can find more information about it here. However, when I tried implementing it, I encountered the error message ...

Struggling to populate a table with data

I've previously sought help on this project and I'm still facing challenges. The code is messy with duplicate functions, making it hard to manage. Currently, my main issue is fetching data from Firebase and updating a table with it. <div cla ...

Setting various colors for different plots within a single chart: A step-by-step guide

I'm currently tackling a project that requires me to showcase two different plots on the same chart, one being a "SPLINE" and the other a "COLUMN". My aim is to assign distinct background colors to each of these plots. Please note that I am referring ...

Angular - Sweetalrt2 automatically takes action before I even have a chance to press OK

I'm currently utilizing Angular-7 for my website project and have integrated sweetalert2 into it. client.component.ts import { Component, OnInit, ElementRef, NgZone, ViewChild } from '@angular/core'; import { HttpClient } from '@angul ...

Retrieving random data using regular expressions and wildcards

Upon analyzing this specific data structure { _id: ..., data: [ {key: 'articles.0.photos.0.category', value: '...'}, {key: 'articles.0.photos.1.category', value: '...'}, ... ] } ...

What is the best way to handle multiple requests to the same URL in Cypress while waiting?

I am currently developing a Cypress test that involves sending multiple requests to the same URL with varying body content. Essentially, the test modifies input values in the user interface, triggering new server requests. The challenge arises when trying ...

Strategies for aligning tooltips with the locations of dragged elements

One of my projects involves a simple drag element example inspired by Angular documentation. The example features a button that can be dragged around within a container and comes with a tooltip. <div class="example-boundary"> <div ...