Learn how to pass and use viewModel data between different ViewModel functions on separate pages with Knockout JS

Incorporating Knockout.js into my single-page application has brought up a challenge for me. I am looking to transfer the value of one viewmodel data to another viewmodel data in order to minimize duplications in creating the same view. Below is a snippet from my codebase: I have two separate JavaScript files, one containing the Employee ViewModel and the other the Department ViewModel.

      //Employee View
       <div class="Employee-view"  data-role="view" id="employee">
         <div data-role="content" >
           <ul>
             <li foreach:EmployeeData>
              //OnClick of this element should navigate to the Department view and bind all values based on a particular Employee ID 
              <div databind:"click:GetDepartmentDetails">
                <span data-bind:"text:EmployeeId"> <span>
                <span data-bind:"text:EmployeeName"> <span>
                <span data-bind:"text:EmployeeImage"> <span>
             </div> 
            </li>
          </ul>
        </div>
      </div>

     EmployeeViewModel = new EmployeeDetailsViewModel();;
     $(".Employee-view").each(function () {
        ko.applyBindings(EmployeeViewModel, $(this).get(0));
     });


     function EmployeeViewModel(){
        var self=this;
        self.EmployeeData = ko.observableArray([]);
        self.GetEmployee = function(UserName,Password){  
           var UserModel = { UserName: UserName, Password: Password}
           $.ajax({
                type: "POST",
                dataType: "json",
                url: serverUrl + 'xxx/xxx/GetEmployee',
                data: UserModel,
                success: function (data) {
                   self.EmployeeData($.map(data, function (item) {
                     return new EmployeeModel(item);
                   }))
                }
           });
         }

        //Click EVENT
        self.GetDepartmentDetails=(EmployeeData){
          // I have access to all the values in this ViewModel; now I need to pass these values to the DepartmentViewModel and call the required function.
          self.GetEmployeeByDepartment();
        }

     }

     function EmployeeModel(data)
     {
       var self = this;
       self.EmployeeId = ko.observable(data.EmployeeId)
       self.EmployeeName = ko.observable(data.EmployeeName)
       self.EmployeeImage = ko.observable(data.EmployeeImage)
      }

       //Department View
       <div class="Department-view" data-role="view" id="Department">
         <div data-role="content">
           <ul>
             <li   data-bind:"foreach:DepartmentData ">
              <div>
                <span data-bind:"text:DeptId"> <span>
                <span data-bind:"text:DeptName"> <span>
              </div> 
             </li>
           </ul>
         </div>
       </div>

      //Department View Model
      function DepartmentViewModel ()
      {
        var self = this;
        self.DepartmentData = ko.observableArray([]);
        self.GetEmployeeByDepartment = function(item){  
          employeeID = item.EmployeeId
          employeename = item.Employeename
          var DeptModel = { Employeename: employeeID, Employeename: employeename}
          $.ajax({
            type: "POST",
            dataType: "json",
            url: serverUrl + 'xxx/xxx/GetDepratmenDetails',
            data: DeptModel ,
            success: function (data) {
               self.DepartmentData ($.map(data, function (item) {
                 return new DepartmentModel(item);
               }),
            });
          }}
       }

       function DepartmentModel(data)
       {
         var self=this;
         self.DeptId = ko.observable(data.DeptID)
         self.DeptName = ko.observable(data.DeptName)
       }

       DepartmentViewModel = new DepartmentDetailsViewModel();
       $(".Department-view").each(function () {
         ko.applyBindings(DepartmentViewModel, $(this).get(0));
       });

I'm facing an issue with duplication as we were unable to resolve it efficiently. Can someone assist? How to carry the data between different viewmodels in Knockout JS?

Answer №1

Initially, there are numerous typos and incorrect bindings in your view that require immediate attention. For instance:

<ul>
  <li foreach:EmployeeData>  
    <div databind:"click:GetDepartmentDetails">   
        <span data-bind="text:EmployeeId"></span> 
        <span data-bind="text:EmployeeName"></span>
        <span data-bind="text:EmployeeImage"></span>
     <div> 
   <li>
<ul>

It is advisable to create an observable variable in your employeeViewModel to store a new DepartmentViewModel instance. This way, you can easily call any functions through this variable without the need to repeatedly re-apply ko.

Below, I've attempted to utilize your code with dummy data to demonstrate how you may approach this. Example: https://jsfiddle.net/kyr6w2x3/157/

View:

<h1>Employee View</h1>
<div class="Employee-view"  data-role="view" id="employee">
  <div data-role="content" >
    <ul>
      <li data-bind="foreach:EmployeeData">
        <div data-bind="click:$parent.GetDepartmentDetails">
          <span data-bind="text:EmployeeId"></span>
          <span data-bind="text:EmployeeName"></span>
          <span data-bind="text:EmployeeImage"></span>
        </div> 
      </li>
    </ul>
  </div>
</div>

<hr>

<h1>Department View</h1>
<div data-bind="with:DepartmentVM">
  <div class="Department-view" data-role="view" id="Department">
    <div data-role="content">
      <ul>
        <li   data-bind = "foreach:DepartmentData ">
          <div>
            <span data-bind = "text:DeptId"></span>
            <span data-bind = "text:DeptName"></span>
          </div> 
        </li>
      </ul>
    </div>
  </div>
</div>

Models :

function EmployeeViewModel() {
  var self = this;
  // Define an observable variable to hold DepartmentVM
  self.DepartmentVM = ko.observable();
  self.EmployeeData = ko.observableArray([]);
  self.GetEmployee = function(UserName,Password){  
    var UserModel = { UserName: UserName, Password: Password}
    $.ajax({
       type: "POST",
       dataType: "json",
       url: serverUrl + 'xxx/xxx/GetEmployee',
       data: UserModel,
       success: function (data) {
         self.EmployeeData($.map(data, function (item) {
           return new EmployeeModel(item);
         }))
       }
    });
  }

  // Call GetEmployee()
  self.GetEmployee();

  // Knockout function
  self.GetDepartmentDetails = function (EmployeeData){
    console.log(EmployeeData)
    // Create a new instance of DepartmentViewModel, call functions inside it, pass the data
    self.DepartmentVM(new DepartmentViewModel());
    self.DepartmentVM().GetEmployeeByDepartment(EmployeeData);
  }
}
function DepartmentViewModel () {
  var self = this;
  self.DepartmentData = ko.observableArray([]);
  self.GetEmployeeByDepartment = function(item){  
    // Ensure to use () to get observable variable values like item.EmployeeId()
    employeeID = item.EmployeeId()
    employeename = item.EmployeeName()  

     var DeptModel = { Employeename: employeeID, Employeename: employeename}
     $.ajax({
       type: "POST",
       dataType: "json",
       url: serverUrl + 'xxx/xxx/GetDepratmenDetails',
       data: DeptModel ,
       success: function (data) {
          self.DepartmentData ($.map(data, function (item) {
             return new DepartmentModel(item);
           }))
       }
    });
  }
}

function DepartmentModel(data)
{
  var self = this;
  self.DeptId = ko.observable(data.DeptID)
  self.DeptName = ko.observable(data.DeptName)
}
function EmployeeModel(data)
{
  var self = this;
  self.EmployeeId = ko.observable(data.EmployeeId)
  self.EmployeeName = ko.observable(data.EmployeeName)
  self.EmployeeImage = ko.observable(data.EmployeeImage)
}
var EmployeeVM = new EmployeeViewModel()
ko.applyBindings(EmployeeVM);

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

Ways to display URL parameters on an HTML page without using PHP

I'm currently working on a website using HTML (without PHP) and I'm facing an issue with displaying URL parameters on an appointment confirmation page. The appointment details are being successfully passed through the URL parameters, but I'm ...

What is the best way to pass the value from one JavaScript file to another in the ViewModels and main JavaScript file?

https://i.sstatic.net/pzFAS.jpg Within the login.js file, a REST API is returning specific values that need to be utilized in the Dashboard.html file. However, the values are not being retrieved successfully in the dashboard.js file. A similar requiremen ...

Executing XSS Reflected Attack by Loading an External JS Script via POST Parameter

Experimenting with XSS attacks on my vbox machines, just for kicks! I have two .html files - one works and the other doesn't. The file that works contains: <html> <head></head> <body> <form method="post" action=&q ...

What specific URL should be included in a JavaScript ajax request?

As I delve into creating a JSON file using an ajax request in javascript, confusion strikes when it comes to determining the appropriate URL. With no previous experience working server side and relying on WAMP server 3.0.6 to host my project-in-the-works ...

React component's state is not being correctly refreshed on key events

Currently facing an issue that's puzzling me. While creating a Wordle replica, I've noticed that the state updates correctly on some occasions but not on others. I'm struggling to pinpoint the exact reason behind this discrepancy. Included ...

Error: Unable to encode data into JSON format encountered while using Firebase serverless functions

I am currently working on deploying an API for my application. However, when using the following code snippet, I encountered an unhandled error stating "Error: Data cannot be encoded in JSON." const functions = require("firebase-functions"); const axios = ...

Is there a way to display the button only when the user is able to enter an email in the input field?

I have a form for users to update their profile and a button to delete their account. I want the delete account button to only be visible if the user enters their email. $(document).ready(function() { var user_email = $('input[name="emp_email"]&a ...

A guide on utilizing nodejs to automatically open the default browser and direct it to a specific web address

I am currently developing a program using Node.js. One of the features I aim to implement is the ability to launch the default web browser and direct it to a particular URL. I want this functionality to be compatible across Windows, Mac, and Linux operat ...

"Navigate with ease using Material-UI's BottomNavigationItem and link

What is the best way to implement UI navigation using a React component? I am currently working with a <BottomNavigationItem /> component that renders as a <button>. How can I modify it to navigate to a specific URL? class FooterNavigation e ...

A dynamic display featuring four columns that showcase unique content every day of the week

As a beginner in coding, I am attempting to design a page with 4 columns that will showcase different titles and descriptions each day of the week. My goal is to have a set of titles and descriptions displayed on Monday, a different set on Tuesday, and so ...

Is there a way to incorporate electron methods within Svelte files, specifically in Svelte 3, or is there an alternative approach to achieve this integration?

Currently, I am deep into a project that involves Svelte 3 and Electron 12.0.5 working together harmoniously. For managing hash routing, I have integrated the svelte-spa-router package into my setup. Here is a glimpse of how my project structure appears: n ...

Why does the second JavaScript form validation not function correctly when compared to the first?

Here is a form that I have created: <form action="next.html" id="userInput" method="post" onsubmit="return validate();"> Age: <input type="text" name="age" id="age"/> function validate() { var age = document. ...

Interactive World Map with Fluid Motion Animation built using HTML, CSS, and JavaScript

I am in need of an uncomplicated way to visually represent events taking place around the globe. This involves creating a 2D image of a world map, along with a method to show visual alerts when events occur at specific geographical coordinates [lat, lng]. ...

What is the best way to integrate Emotion styled components with TypeScript in a React project?

Currently, I am delving into TypeScript and attempting to convert a small project that utilizes Emotion to TypeScript. I have hit a roadblock at this juncture. The code snippet below export const Title = styled.div(props => ({ fontSize: "20px", ...

The construction was unsuccessful due to errors in the webpack process

I encountered a sudden error in my Next.js app. Is there any solution available to resolve this issue? ./pages/_app.tsx Error: [BABEL] C:\Projects\skribeNew\app-web\pages\_app.tsx: You provided us with a visitor for the node type T ...

Incorporate an Ajax request onto an existing link within a div element

Here is what I have: <div id="div-for-ajax-onclick"> <a href="http://www.google.com">Link to google</a> </div> $("#div-for-ajax-onclick").click(function() { // update database }); I am looking for a solution where if someone c ...

Why isn't my div displaying in JavaScript?

Currently working on a project for the Odin Project front-end web development. My task involves creating a grid using javascript/jQuery. I attempted to use the createElement method but have encountered an issue in making the div visible within the html. Am ...

What steps can I take to set a strict boundary for displaying the address closer to the current location?

While the autocomplete feature works perfectly for me, I encountered an issue where it suggests directions away from my current location when I start typing. I came across another code snippet that uses plain JavaScript to solve this problem by setting bou ...

What is causing the React text component to fail to show changes made to my array state?

I am currently in the process of learning React Native. I have been working on an app and encountered an issue while attempting to update individual elements within an array. Here is an example of the code: function MyApp() { const [array, setArray] = ...

jQuery combined with VanillaJS provides the quickest way to select elements on a web

As I work on developing my jQuery application, I find myself pondering the most efficient method for selecting elements with jQuery. With countless elements on this webpage, each possessing a unique ID, I currently have this implementation: $("#main-conta ...