Passing a Value from Child to Parent Function in Meteor: A Complete Guide

I am trying to pass the value of a result from a child element to its parent element. Initially, I used Session.set and Session.get which worked fine but I realize that using Sessions globally is not considered good practice. So, I attempted to utilize reactive vars or reactive dicts instead, however, they only return an object as a result. How can I extract specific data from that object or what approach should I take? (I am storing JSON data inside the ReactiveVar or Dict and I am aware that it might not be ideal with JSON. Thank you for your assistance!

Template.companyCreate.helpers({
    CompanyName : function () {
        if (Meteor.user() || Roles.userIsInRole(Meteor.user(),['admin','adminCreator'], 'companyAdmin')) {
            Meteor.call('findCompany', function(err, result) {
                if (err) {
                    console.log(err.reason)
                }
                else {
                    // Will need to handle the result here and pass it to the parent function
                }
            });
            return // Need to retrieve the result passed from the child function and return it for CompanyName
        }
        else {
            Router.go('/nemate-prava')
        }
    },

UPDATED CODE

    Template.companyCreate.onCreated(function Poruke() {
    this.message = new ReactiveVar(' ');

    let self = this;
    let user = Meteor.user();
    let companyNameHandler = Template.currentData().companyNameHandler;
    self.companyName = new ReactiveVar();

    if (user && Roles.userIsInRole(user,['admin','adminCreator'], 'companyAdmin')) {
        Meteor.call('findCompany', function(err, result) {
            if (err) {
                console.log(err.reason)
            }
            else {
                self.companyName.set(result);
                companyNameHandler(result);
                }
            });
        }
    else {
        Router.go('/nemate-prava')
    }
}); 

Template.companyCreate.helpers({
    message: () => { return Template.instance().message.get() },

    isNotInRole : function() {
        if (!Meteor.user() || !Roles.userIsInRole(Meteor.user(),['admin','adminCreator'], 'companyAdmin')) {
            return true;
        }
        else {
            return false;
        }
    },

    CompanyName : function () {
        return Template.instance().companyName.get();
    }
});

Template.companyCreate.events({
    'submit form': function(event, template) {
        var Ime = event.target.Ime.value;
        event.preventDefault();
        Meteor.call('companyCheck', Ime, function(error, result) {       
            if (error) {
                console.log(error.reason);
                template.message.set(error.reason);
                alert(error.reason);
            }
            else {
                event.target.Ime.value = "";
                console.log('Kompanija je uspesno kreirana!');
                template.message.set("Uspesno!");
            }
        })
    },
});

Method:

    'findCompany'(){
        ImeKompanije = firma.findOne({AdminID: this.userId}).ImeKompanije
        if (typeof ImeKompanije == 'undefind') {
            throw new Meteor.Error(err, "Greska!");
        }
        return ImeKompanije;

    },
});

Router:

    Router.route('/comp/:ImeKompanije', {
    name: 'companyProfile',
    template: 'companyProfile',
    waitOn: function() {
        return Meteor.subscribe('bazaFirmi', this.params.ImeKompanije)
    },
    action: function() {
        this.render('companyProfile', {
            data: function() {
                return firma.findOne({ImeKompanije: this.params.ImeKompanije});
            }
        });
    },
});

Answer №1

Alright, there's a lot going on here that we need to unpack. Let's take it step by step.

if (Meteor.user() || Roles.userIsInRole(Meteor.user(),['admin','adminCreator'], 'companyAdmin')) {

It seems like this line is supposed to check if the user is an admin, but it's actually checking if the user is logged in. If you intended to check for admin status, replace "||" with "&&".

A larger issue is that you're making a server call within a helper function. Helpers are meant to simply return data and should not have side effects like server calls or redirecting users.

To address this, let's move the server call to the onCreated() function and store the company name in a reactive variable which can then be accessed by the helper. We'll also set up a way to pass the company name back to the parent template.

Template.companyCreate.onCreated(function() {
    let self = this;
    let user = Meteor.user();
    let companyNameHandler = Template.currentData().companyNameHandler;

    self.companyName = new ReactiveVar();

    if (user && Roles.userIsInRole(user,['admin','adminCreator'], 'companyAdmin')) {
        Meteor.call('findCompany', function(err, result) {
            if (err) {
                console.log(err.reason)
            }
            else {
                self.companyName.set(result);
                companyNameHandler(result);
            }
        });
    }
    else {
        Router.go('/nemate-prava')
    }
});

Now the helper function simply returns the data stored in the template's reactive variable:

Template.companyCreate.helpers({
    CompanyName : function () {
        return Template.instance().companyName.get();
    }
});

Finally, we need to set up a handler to pass the data back to the parent template. It's best practice to avoid the client reaching back up to its parent, so we'll have the parent template provide a function that the child can call when ready. Here's how you can implement it:

<template name="Parent">
    {{> companyCreate companyNameHandler=getCompanyNameHandler}}
</template>

Template.Parent.helpers({
    getCompanyNameHandler() {
        let template = Template.instance();

        return function(companyName) {
            console.log(companyName);
            // You can access the parent template using the closure "template"
        }
    }
});

The parent template's helper function returns a callback function that will execute in the parent's scope when called by the child. By setting up a variable "template" in the closure, you can access reactive vars belonging to the parent template.

UPDATE: If the handler is not available directly within the Meteor.call() scope, you can try accessing it through a reactive variable as shown below:

Template.companyCreate.onCreated(function() {
    let self = this;
    let user = Meteor.user();
    self.companyNameHandler = new ReactiveVar(Template.currentData().companyNameHandler);

    self.companyName = new ReactiveVar();

    if (user && Roles.userIsInRole(user,['admin','adminCreator'], 'companyAdmin')) {
        Meteor.call('findCompany', function(err, result) {
            if (err) {
                console.log(err.reason)
            }
            else {
                self.companyName.set(result);
                let fn = self.companyNameHandler.get();
                fn(result);
            }
        });
    }
    else {
        Router.go('/nemate-prava')
    }
});

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

Tips for capturing the current terminal content upon keypress detection?

After successfully installing the terminal on a test page, I am looking to highlight matching parentheses within it. This is similar to what is done in this example: I have a working solution in place and now need to integrate it with the terminal. ...

Display previous messages in React JS chat when scrolling upwards

I am currently working on a chat application, as depicted in the image. Once the chat is initiated, it automatically scrolls down to display the most recent messages. My goal is to implement a feature where when a user scrolls up to reach the oldest mess ...

Having trouble with filtering JSON data in AngularJS?

I'm sorry if this question has already been answered. I tried looking for solutions on other websites, but couldn't understand them. I am attempting to filter JSON data within the ng-repeat function, but whenever I try to input something, it does ...

Stop the duplication of downloading JavaScript files

When it comes to my website, I have incorporated sliders that stream videos from Vimeo. Upon running a check on GTMetrix, I noticed an overwhelming number of http requests. Looking at the waterfall, I discovered numerous duplicate downloads of javascript, ...

Semantic UI form validation is initiated by clicking any button

Within my Semantic UI form (<div class="ui form">), it seems that every button is triggering the form validation, even if it's not a submit button. I have two different types of buttons below: <button class="ui blue right labeled icon prima ...

Creating an HTML list based on a hierarchical MySQL table structure

I have retrieved a hierarchical table showing different elements and their parent-child relationships as follows: id| name | parent_id | header 1 | Assets | 0 | Y 2 | Fixed Assets | 1 | Y 3 | Asset One | 2 | N 4 | ...

Incorporate SVG files into a TypeScript React application using Webpack

I am trying to incorporate an SVG image into a small React application built with TypeScript and bundled using Webpack. However, I am encountering an issue where the image is not displaying properly (only showing the browser's default image for when n ...

Prevent sticky div from overlapping with footer

I currently have a social link menu that is fixed to the left side of my page, structured like this: <footer id="colophon"></footer> <div> <nav> <ul id="social"> <li>Link1</li> ...

Discover and select an element based on its partial `onclick` attribute value

Can an element be clicked through selenium based on a partial value of an onclick attribute? There are several input elements on the page, and I am interested in selecting one with a specific string. Examples would include: <input name="booksubmit" t ...

Tips for transferring large data without a page redirect using jQuery's post method:

Seeking advice on how to send large data via jQuery POST without redirecting the page. I'm working on a mobile chat project where communication between user app and server is done using JSON. The issue arises when dealing with big data as the jsonGet ...

What is causing json_decode to not work on this specific json object?

I've been working on a PHP script that receives a JSON object from http://www.reddit.com/search.json via an HTTP GET request. After some testing, I can confirm that the script successfully retrieves the JSON object. However, when I try to use json_dec ...

How can I utilize customToJSON in Sails 1.0 within an Action2 function?

Currently, I am facing an issue with my user model that requires the implementation of a customToJSON method to remove the password field from the returned JSON object. Everything works fine when I include "responseType" in the "exits" with a value of "jso ...

Transitioning create-react-app from JavaScript to Typescript

A few months ago, I began a React project using create-react-app and now I am interested in transitioning the project from JavaScript to TypeScript. I discovered that there is an option to create a React app with TypeScript by using the flag: --scripts-v ...

I attempted to post a collection of strings in ReactJS, only to receive a single string response from the Web

I was troubleshooting an issue where only one string from ReactJS was being sent to WebApi instead of an array of strings. Below is the ReactJS code snippet I used: import React, { useState } from "react"; import axios from "axios"; e ...

Access and process all JSON files within a folder that is constantly being updated

I have a situation where multiple JSON files are stored in a directory that will be constantly updated by users. Users have the ability to add categories, which results in new JSON files being created in the directory, and they can also remove categories, ...

Efficient method for deleting a specific item from a JSON object in React.js

Within the REACT JS framework, I am managing a JSON object in the state component "myrecords". The items within this object are organized by their respective Company Names and have the following structure: { "Master Automotives": [ { ...

Create genuinely private methods within an ES6 Module/Class specifically for use in a nodejs-exclusive environment, ensuring that no data is exposed

Although there are no true private methods within ES6 classes, I stumbled upon something interesting while experimenting... While it's not possible to completely hide object properties, I attempted to follow OOP principles by dividing my classes into ...

What is the process for integrating Android Java code with Node.js code?

I have some code that I am trying to integrate with Node.js for Firebase notifications on my Android application. I found a blog post outlining the implementation here: The Node.js code listens to changes in my Firebase Database and triggers notifications ...

Modifying the value of an animated status bar using the same class but different section

I need the status bars to work individually for each one. It would be great if the buttons also worked accordingly. I have been trying to access the value of "data-bar" without success (the script is able to process the "data-max"). However, the script see ...

Is there a way to refresh a webpage without the need to reload it

Imagine a scenario where a tab on a website triggers the loading of a specific part of the webpage placed within a div. For example, clicking on a tab may trigger the loading of a file named "hive/index.php". Now, if a user selects an option from an auto ...