Dynamic Replacement of Strings in Angular using Typescript

As I delve into the realm of creating an offer letter, a perplexing challenge arises - how can I seamlessly replace specific placeholders with details of selected candidates without leaning on jquery or JS? No $, no document.getelementbyId. A pure TypeScript approach is what I seek. Here's the intricate scenario at play:

A virtual template list stands ready, harboring clauses alongside their corresponding textual content.

  templateList = [{

    templateId: 1,
    templateName: "Offer",
    clauses: [
      {
        clauseName: "Introduction",
        clauseId: 1,
        texts: [
          {
            text: "Greetings <<Name>>, Welcome to the Machine",
            textId: 1,
          }]
      },
      {
        clauseName: "Address",
        clauseId: 2,
        texts: [
          {
            text: "<<Address>>",
            textId: 2,
          }]
      },
      {
        clauseName: "Date Of Joining",
        clauseId: 3,
        texts: [
          {
            text: "We anticipate your arrival on <<DateOfJoining>>",
            textId: 3,
          }]
      },
    ]
  }]

The candidate roster is equally significant:

  candidateList = [
    { name: "Simba", address: "Some Random Cave" },
    { name: "Doe John", address: "line 4, binary avenue, Mobo" },
    { name: "B Rabbit", address: "8 mile road, Detroit" },
    { name: "Peter Griffin", address: "Spooner Street" },
    { name: "Speedy Gonzales", address: "401, hole 34, Slyvester Cat Road" },
    { name: "Morty", address: "Time Machine XYZ" },
    { name: "Brock", address: "pokeball 420, Medic center" },
  ]

An intriguing task ahead - substituting the placeholders enveloped by <<>> within the template text (including the delimiters) with the chosen candidate's name or address from the dynamic list upon clicking.

Let's now shift our gaze to the HTML structures:

<div style="display: block;">
    <button (click)="showTemplate()">Show template</button>
</div>
<hr /><br />
<div class="row">
    <div class="col-4">
        <ul>
            <ol *ngFor="let x of candidateList">
                <a>{{x.name}}</a><br />
                <a><small>{{x.address}}</small></a>
                <hr />
            </ol>
        </ul>
    </div>
    <div class="col-8">
        <div class="templateDiv">
            <div *ngFor="let temp of clauseList">
                <span><strong class="textTemp">{{temp.clauseName}}</strong></span>
                <br/>
                <div *ngFor="let x of temp.texts">
                    <p class="txt">{{x.text}}</p>
                </div>
            </div>
        </div>
    </div>
</div>

The notion of dynamic data points infiltrates this narrative quite subtly. Explore a live demo showcasing this synergy via this link.

Your insights and expertise are paramount here!

Answer №1

Component module.ts

applicantList = [
        { name: "Scar", address: "Lair on the Hill", dateOfJoin: "10/2/2020" },
        { name: "Jack Sparrow", address: "7 Seas, Pirate Island" },
        { name: "Shrek", address: "Swamp Fortress" },
        { name: "Mickey Mouse", address: "Disney Lane" },
        { name: "SpongeBob SquarePants", address: "Pineapple Under The Sea" },
        { name: "Jerry", address: "Mouse Hole" },
        { name: "Buzz Lightyear", address: "Space Command Center" }
      ];

      templateList: Object[] = [];

      displayTemplate(name: string, address: string, dateOfJoin: string) {
        this.templateList = [];
        for (let element of this.applicantList) {
          if (element.templates != null) {
            for (let template of element.templates) {
              this.setTemplateText(template, address, name, dateOfJoin);
              this.templateList.push(template);
            }
          }
        }
        console.log("Template list", this.templateList);
      }

      setTemplateText(template: any, address, name, dateOfJoin) {
        let text = template.contents[0].text;
        if (template.type === "Intro") {
          const nameToSwap = this.getRevisedName(text);
          if (name !== undefined) {
            template.contents[0].text = text.replace(nameToSwap, name.concat(","));
          } else template.contents[0].text = text.replace(nameToSwap, "Not Available");
        } else if (template.type === "Location") {
          if (address !== undefined)
            template.contents[0].text = text.replace(text, address);
          else template.contents[0].text = text.replace(text, "N/A");
        } else if (template.type === "Joining Date") {
          const joinDateToReplace = this.getRevisedDateOfJoin(text);
          if (dateOfJoin !== undefined)
            template.contents[0].text = text.replace(joinDateToReplace, dateOfJoin);
          else template.contents[0].text = text.replace(joinDateToReplace, "N/A");
        }
        console.log("Template Text ==", template.contents[0].text);
      }

      getRevisedName(text: string) {
        const splitArray = text.split(" ");
        if (splitArray[2].includes(",")) 
          return splitArray[1] + " " + splitArray[2];
        else return splitArray[1];
      }

      getRevisedDateOfJoin(text: string) {
        const splitArray = text.split(" ");
        return splitArray[5];
      }

Component template.html

<hr /><br />
<div class="row">
    <div class="col-4">
        <ul>
            <ol *ngFor="let item of applicantList">
                <a (click)="displayTemplate(item.name,item.address,item.dateOfJoin)">{{item.name}}</a><br />
                <a (click)="displayTemplate(item.name,item.address,item.dateOfJoin)"><small>{{item.address}}</small></a>
                <hr />
            </ol>
        </ul>
    </div>
    <div class="col-8">
        <div class="templateDiv">
            <div *ngFor="let temp of templateList">
                <span><strong class="textTemp">{{temp.type}}</strong></span>
                <br/>
                <div *ngFor="let content of temp.contents">
                    <p class="txt">{{content.text}}</p>
                </div>
            </div>
        </div>
    </div>
</div>

I have updated your code, specifically the displayTemplate method.

Answer №2

I have made some changes to the showTemplate function so that now it properly works when you add something in the clause, although it may not work if the names of the clauses are unknown.

showTemplate(name: string, address: string, dateOfJoin: string) {
    this.clauseList = [];
    let tempList = new Array<any>();
    tempList = JSON.parse(JSON.stringify(this.templateList));
    for (let template of tempList) {
      if (template.clauses != null) {
        for (let clause of template.clauses) {
          this.setClauseText(clause, address, name, dateOfJoin);
          this.clauseList.push(clause);
        }
      }
    }
    console.log("Clause list", this.clauseList);
  }

  setClauseText(clause: any, address, name, dateOfJoin) {
    let text = clause.texts[0].text;
    if (clause.clauseName === "Introduction") {
         const nameToReplace = this.getText(text);
      if (name !== undefined) {
        clause.texts[0].text = text.replace(nameToReplace, name.concat(","));
      } else clause.texts[0].text = text.replace(nameToReplace, "N/A");
    } else if (clause.clauseName === "Address") {
       const addressToReplace = this.getText(text);
      if (address !== undefined)
        clause.texts[0].text = text.replace(addressToReplace, address);
      else clause.texts[0].text = text.replace(text, "N/A");
    } else if (clause.clauseName === "Date Of Joining") {
      const dateOfJoinToReplace = this.getText(text);
      if (dateOfJoin !== undefined)
        clause.texts[0].text = text.replace(dateOfJoinToReplace, dateOfJoin);
      else clause.texts[0].text = text.replace(dateOfJoinToReplace, "N/A");
    }
    console.log("ClasueText ==", clause.texts[0].text);
  }

  getText(text: string) {
    const splitArray = text.split(" ");
    for (let elementSplit of splitArray)
      if (elementSplit.includes("<<")) return elementSplit;
  }
}

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

Obtain serialized information from php using ajax

I am currently working with a php script that returns serialized data. I am trying to retrieve this data using the $.ajax() method from jQuery 1.7. You can find an example here. $.ajax({ url: 'http://input.name/get.php?do=lookup' + '&am ...

Tips for transferring information from Javascript to a PHP script

For the code in JavaScript that I have written to transfer data to PHP, I am encountering an issue where it doesn't seem to work properly. Here is the code snippet: function codeAddress() { var address = document.getElementById('address') ...

What is the best way to incorporate a function that works seamlessly with elements?

For the elements with corresponding 'li' that has a selected class, I need to set the selected property only for those specific 'option' elements. The value is determined by the data-input-value attribute in the 'li' and the v ...

Issue with vue-router not displaying template for nested routes

My route configuration looks like this: const routes = [{ path: '/', component: Home, children: [ { path: "/health", children: [ { path: 'overview', ...

Where can I locate the list of events supported by CKEditor 4?

Looking for the list of available events I attempted to locate the event list in the official documentation, but unfortunately came up short. I resorted to searching through the source code using .fire("/s+") to identify all available events. However, thi ...

React-Native 0.1.17 Navigator Bar: Enhancing User Navigation Experience

An issue arose after upgrading my react-native 0.1.15 app to version 0.1.17 - I'm now encountering an 'Unable to download JS bundle error'. Upon investigation, I found the error in my code: var SportsSocial = React.createClass({ component ...

Crafting upward sliding messages: a step-by-step guide

Is there a way to implement sliding messages that move upwards, similar to the example shown here? I attempted to achieve this effect using slideup, but unfortunately, it did not work. Also, I would like to include a button in the corner to close the mes ...

Symfony2: Using Ajax to send data to a controller

I have implemented a search input on my website that allows users to search for content within my database. I want this search input to function similarly to the search bar on Facebook, using Ajax for instant searching. Despite trying various code snippets ...

The functionality of event.preventDefault is not working as expected

Using AJAX, I successfully loaded data into a div. <div id="container"> <a class="hello" href="abc.php">hello</a> // content loaded via AJAX <div> Currently, I am trying to implement jQuery: <script type="text/javascript" ch ...

Tips for resolving the TypeScript error related to the global object in Node.js

I am currently working on a project following the steps outlined in this guide https://vercel.com/guides/nextjs-prisma-postgres to develop a full stack application. However, I have encountered an error with TypeScript in the code snippet below: import { Pr ...

Nothing happens when the render_template method receives AJAX content in Flask with Python and JavaScript

When a certain condition is met, I am using ajax to pass data to my python function: if (lesson.length === 0) { $.ajax( { type:'POST', contentType:'application/json& ...

What is the best way to activate the initCallback function of Bootstrap Javascript after implementing lazy loading?

Although the Bootstrap-native JavaScript may not be directly necessary until user interaction begins, I am considering lazy loading it to save a few KB. However, I have encountered a minor issue with the initialization function initCallback(); because DOMC ...

Using AngularJS and SpringMVC for uploading multiple files at once

Having recently delved into the world of angularJS, I've been attempting to upload a file using angular JS and Spring MVC. However, despite my efforts, I have not been able to find a solution and keep encountering exceptions in the JS Controller. Bel ...

Utilizing AngularJS to bind form fields with select boxes to enable synchronized data. Modifying the selection in the dropdown should dynamically

Currently, I am working on an input form that involves a select with various options. Depending on the user's selection, three additional fields need to be populated accordingly. For instance: If the user picks Option1, then the three other fields s ...

JavaScript is acting buggy and throwing an error because it cannot access the variable 'r' before it has been

Utilizing THREE.js's raycaster, I successfully linked a mouse event to my 3D model in my development environment. However, when I built it using VUE.js and ran it in the production environment, I encountered an error: Uncaught ReferenceError: Cannot a ...

HTML5 Adaptive Button Arrangement

I'm working on making my buttons adaptive to screen orientation changes on mobile devices. My goal is to ensure that the website remains user-friendly regardless of how it's being accessed. I know how to adjust button size using CSS in scripts, b ...

event triggered when a div element with ngIf directive is displayed

I came across an issue on a forum at: There is a div with an ngIf condition, and I want to detect when the div is rendered. I read that you can use the AfterContentInit event for this purpose. I tried implementing the example from the article mentioned ab ...

How to Make Words Stand Out in a Textbox using Angular NgStyle and input::first-line Trick?

Is there a way to highlight the text in a textbox using Angular and Material design? I've tried the code below but it's not working for me. I'm looking to apply the highlighting conditionally based on a boolean variable called 'highlig ...

Receiving a response of success or failure when using android.SmsManager.sendTextMessage() in a NativeScript/Android application

I have a question regarding sending an SMS from my NativeScript mobile application. Below is the code I am using: sendSms(numbers, body) { let sms = android.telephony.SmsManager.getDefault(); sms.sendTextMessage(numbers, null, body, null, ...

Having trouble with the jQuery file upload plugin when trying to upload files larger than 5 MB

I successfully incorporated the jQuery file upload plugin into my Codeigniter project to allow users to upload files of any extension. I even managed to increase the upload file size limit to 50 MB. However, I encountered an error when attempting to upload ...