Setting a variable equal to ViewModel causing error


#1

Hi,

NativeScript Nooby.

Setting a variable equal to my UserViewModel is causing an error

tns version: 3.4.3
"nativescript-theme-core": “~1.0.4”,
“tns-core-modules”: "~3.4.0"
iOS build

So, I started an app which has the following structure (in case the structure makes a difference)
I’ve just left in the important/relevant folders


/app/
  /shared
    /view-models
      user-view-model.js (user model)*
  /views
    /tabs
      /home
        home-components.xml (home view file) *
        home-components.js (home code-behind) *
      /help
      /settings
        tabs-home.xml (this is where the tab code is, it calls tab content as ‘components’ under /views)
        tabs-home.js (tabs cod-behind file)

Here is a code snippet from the user-view-model (unfinished but will call out to an API):

/* /shared/user-view-model.js */

var config = require("~/shared/config");
var fetchModule = require("fetch");
var observableModule = require("data/observable");

function User(info) {
  info = info || {};

  // You can add properties to observables on creation
  var viewModel = new observableModule.fromObject({
      email: info.email || "wittner@here.com",
      password: info.password || "password"
  });

  viewModel.signin = function() {
      return fetchModule.fetch(config.apiUrl + "user/" + config.appKey + "/login", {
          method: "POST",
          body: JSON.stringify({
              username: viewModel.get("email"),
              password: viewModel.get("password")
          }),
          headers: getCommonHeaders()
      })
      .then(handleErrors)
      .then(function(response) {
          return response.json();
      })
      .then(function(data) {
          config.token = data._kmd.authtoken;
      });
  };

  viewModel.register = function() {
      console.log('register');
  };

  return viewModel;
}
…

home-components-js snippet:

/* home-components.js */

var frameModule = require("ui/frame");
var observableModule = require("data/observable");
var UserViewModel = require("~/shared/view-models/user-view-model");
var page;
var email;

var user = new observableModule.fromObject({
  email: "user@domain.com",
  password: "password"
});

var user = new UserViewModel();

exports.onLoaded = function(args) {
    page = args.object;
    page.bindingContext = user;
};

exports.signIn = function() {
    user.singIn();
};

exports.signUp = function() {
  var topmost = frameModule.topmost();
  topmost.navigate("views/signup/signup");
};
…

Here’s the error I get in the console when I run this. The app by the way works without error up to the point where I make user = new UserViewModel(). That seems to be the part that’s breaking everything. I can’t figure out if it’s because of the app structure os whether I’m not instantiating the UserViewModel correctly. Any help appreciated

file:///app/tns_modules/tns-core-modules/ui/builder/builder.js:208:56: JS ERROR Error: Building UI from XML. @file:///app/views/tabs/tabs-home.xml:26:13

This is the line being complained about:

        <TabViewItem title="Home" ios:iconSource="res://tabIcons/home">
          <TabViewItem.view>
            <home:home-component/> <-- This is line 26
          </TabViewItem.view>
        </TabViewItem>

Just to re-iterate - If I take out user = new UserViewModel() and fake up the user var, no errors. But if I make ANYTHING equal to UserViewModel() I get the above error


#2

What is the last line in that file?


#3

Thanks multishiv19, the last couple of lines to the end are the closing off of the TabView items, closing of the TabView and end Page tag, here they are:

      </TabView.items>
    </TabView>

</Page>

#4

How you are exporting User?


#5

We’re asking about last lines of user-view-model.js file.
Not the xml file.


#6

Ok. It was late in the evening, doh! The code is using the Grocery app pattern from NativeScript’s site. Here is the full user-view-model file. Bear in mind that for testing I was just trying to return a model from viewModel.signin to keep it simple. There was no call to the api, something like:

viewModel.signin = function() {
return viewModel;
};

contents of full file:

var config = require("../../shared/config");
var fetchModule = require("fetch");
var observableModule = require("data/observable");

function User(info) {
  info = info || {};


  var viewModel = new observableModule.fromObject({
      email: info.email || "wittner@here.com",
      password: info.password || "password"
  });

  viewModel.signin = function() {
      return fetchModule.fetch(config.apiUrl + "user/" + config.appKey + "/login", {
          method: "POST",
          body: JSON.stringify({
              username: viewModel.get("email"),
              password: viewModel.get("password")
          }),
          headers: getCommonHeaders()
      })
      .then(handleErrors)
      .then(function(response) {
          return response.json();
      })
      .then(function(data) {
          config.token = data._kmd.authtoken;
      });
  };

  viewModel.register = function() {
      console.log('register');
  };

  return viewModel;
}

function getCommonHeaders() {
    return {
        "Content-Type": "application/json",
        "Authorization": config.appUserHeader
    }
}

function handleErrors(response) {
    if (!response.ok) {
        console.log(JSON.stringify(response));
        throw Error(response.statusText);
    }
    return response;
}

#7

It should be an empty object since you are not exporting anything from user-view-model.js. Add below line at the end of user-view-model.js to export your function that returns ViewModel.

exports.UserModel = User;

Then change new UserViewModel() to

var user = UserViewModel.UserModel();

#8

@ manojdcoder Everything started to work after those changes. I am now getting data from API server. Many thanks manojdcoder! Seems like a basic error but learning NativeScript means keeping a lot of balls in the air :slight_smile: thanks again,

p.s Is there a way to add this as the correct answer?

Wittner


#9

You will have an option to mark that as solution.

Besides if you don’t mind, I would call that learning JavaScript rather NativeScript and suggest you to spend nice time in basics of CommonJS modules so coding in NativeScript becomes piece of cake.


#10

yeah, that’s fair enough to say - I don’t have a lot of experience with CommonJS modules