0

I want to send value of result from child to parent element. I used Session.set and Session.get and it works fine but I know that is not good practice because Sessions are global. So, I wanted to try something like reactive var or reactive dict but both of them are giving me only object as a result. What should I do or how should I take specific things from that object? (I am storing JSON inside that ReactiveVar or Dict and I know that they are really bad with JSON. Thank you for help!

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 {
                    //this is where I want to take result and give it to parent function
                }
            });
            return //this is where I want to take result that was given from child function and return it to 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});
            }
        });
    },
});
  • Possible duplicate of [How to remove a particular element from an array in JavaScript?](http://stackoverflow.com/questions/5767325/how-to-remove-a-particular-element-from-an-array-in-javascript) –  Apr 26 '17 at 10:54

1 Answers1

1

ok, there's a lot to unwind here. let's start with something small.

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

i think this line is meant to say, "if the user is an admin". but it's really saying, "if the user is logged in." if you meant the first one, then change the "||" to an "&&".

bigger issue is you're making a server call in a helper. helpers can get called over and over, so think of them as something that simply returns data. it should not have any side effects, such as making a server call or (yikes) re-routing the user.

so let's move all that side effect code to the onCreated() and capture the company name so it can be returned from the helper. We'll also get set up to return the company name to the parent.

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 is really simple, it just returns the data that was saved to the template's reactive var:

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

the last part is setting up the handler to return the data to the parent. it's bad form to have the client reaching back up to its parent, so i usually have the parent give to the child a function it can call. usually i'll do that when the child says, "i've done my work," but here we can use it to provide that data. i'll have to make some assumptions on what your parent looks like.

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

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

        return function(companyName) {
            console.log(companyName);
            // you can also access the parent template through the closure "template"
        }
    }
});

the parent's helper returns a function that is passed to the client. when the client calls it, it will execute in the parent's closure. you can see i set up a variable called "template" that would allow you to, say, access reactive vars belonging to the parent.

UPDATE: in case the handler isn't known as is inside the Meteor.call() scope, we can try using it through a reactive var.

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')
    }
});
zim
  • 2,396
  • 2
  • 13
  • 13
  • TypeError: Cannot read property 'companyNameHandler' of null I think that the problem is with: `let companyNameHandler = Template.currentData().companyNameHandler` Method what we call here is taking ID of current user, find witch company has ID of that user inside her fields(because on creation Company saves her admin ID inside her fields), and them method returns name of that Company. –  Feb 02 '17 at 13:57
  • That handler needs to be defined somewhere. I have code in my answer that shows it defined in the parent and passed to the child. Do you have code like that? – zim Feb 02 '17 at 14:55
  • Yeah, I did all things you said. –  Feb 02 '17 at 15:13
  • for the error you describe, yes it sounds like there's an issue with how companyNameHandler is set up. i would first check to see if it's correctly defined in Template.currentData(). if so, then the question is why is its use inside Meteor.call() not working? if it's not defined in Template.currentData(), then the question is was it passed in right from the parent? i suspect it's a problem inside Meteor.call(), so i'll update my code to put the handler in a reactive var; that should definitely work. – zim Feb 02 '17 at 15:23